Exception Handling in Java — try catch finally, Custom Exceptions & Best Practices

Exception Handling in Java — try catch finally, Custom Exceptions & Best Practices

JavaScript is one of those languages where knowing the right tricks can save you hours of debugging and make your code dramatically cleaner. Whether you are just getting started or have been writing JavaScript for years, there are always a few patterns and behaviours that are worth understanding deeply — not just knowing what they do, but understanding why they work the way they do.

In this post we will go through five practical JavaScript tips and tricks that every developer should know. These are not obscure one-liners for showing off — they are genuinely useful patterns you will use in real projects.

1. Always Use === Instead of ==

This is probably the single most important habit to build early in JavaScript. The difference between == and === trips up beginners and occasionally catches experienced developers off guard too.

== is the loose equality operator. Before comparing two values, it performs type coercion — meaning it automatically converts one or both values to the same type before checking if they are equal. This leads to some genuinely surprising results:

// == performs type coercion before comparing
[10] == 10      // true  — array is converted to number 10
'10' == 10      // true  — string '10' is converted to number 10
[]   == 0       // true  — empty array is converted to 0
''   == false   // true  — empty string is falsy, so is false
null == undefined // true — loose equality treats these as equal

=== is the strict equality operator. It compares both the value and the type without any conversion. If the types are different, it immediately returns false:

// === compares value AND type — no conversion
[10] === 10      // false — array is not a number
'10' === 10      // false — string is not a number
[]   === 0       // false — array is not a number
''   === false   // false — string is not boolean
null === undefined // false — different types

The rule is simple: always use === by default. Only use == when you specifically need type coercion, which is rare. Most style guides and linters like ESLint enforce this rule automatically.

Beyond correctness, === is also slightly faster because the JavaScript engine skips the type conversion step entirely.

2. Make Use of Falsy Values

In JavaScript, every value is either truthy or falsy. A falsy value is one that evaluates to false when used in a boolean context (like an if statement). There are exactly six falsy values in JavaScript — no more, no less:

  • false — the boolean false
  • 0 — the number zero (also -0 and 0n)
  • "" — an empty string (single or double quotes)
  • null — intentional absence of a value
  • undefined — a variable that has been declared but not assigned
  • NaN — Not a Number (result of invalid arithmetic)

Everything else in JavaScript is truthy — including empty arrays [], empty objects {}, the string "0", and the string "false".

// Checking if a variable has a meaningful value
if (!variable) {
  // Runs when variable is false, 0, "", null, undefined, or NaN
  console.log("Variable has no value");
}

// Practical examples
let username = "";
if (!username) {
  console.log("Please enter a username"); // runs — empty string is falsy
}

let userAge = 0;
if (!userAge) {
  console.log("Age is required"); // runs — 0 is falsy (watch out for this!)
}

let userData = null;
if (!userData) {
  console.log("No user data found"); // runs — null is falsy
}

Watch out: 0 being falsy can catch you off guard. If a user's age or score is legitimately 0, a simple if (!value) check will incorrectly treat it as missing. In those cases use value === undefined or value === null instead of relying on falsy checking.

3. Use Short-Circuit Evaluation for Cleaner Conditionals

JavaScript evaluates logical expressions from left to right and stops as soon as the result is determined. This behaviour — called short-circuit evaluation — can be used to write much cleaner conditional code.

The || (OR) operator — use a default value

// Without short-circuit
function greet(name) {
  if (!name) {
    name = "Guest";
  }
  console.log("Hello, " + name);
}

// With short-circuit — much cleaner
function greet(name) {
  name = name || "Guest";
  console.log("Hello, " + name);
}

greet("Randhir"); // Hello, Randhir
greet();          // Hello, Guest

The && (AND) operator — run code only if condition is true

// Without short-circuit
if (user) {
  console.log(user.name);
}

// With short-circuit — same thing in one line
user && console.log(user.name);

The ?? (Nullish Coalescing) operator — only fallback on null/undefined

// || treats 0 and "" as falsy — sometimes not what you want
let count = 0;
let display = count || "No items"; // "No items" — wrong! 0 is a valid value

// ?? only falls back when value is null or undefined
let display2 = count ?? "No items"; // 0 — correct!

The nullish coalescing operator ?? was introduced in ES2020 and is now the preferred way to set default values when you want to preserve 0, false, and empty strings as valid values.

4. Destructuring — Extract Values Cleanly

Destructuring is one of the most useful features added in ES6. It lets you extract values from arrays and objects into individual variables in a single clean line instead of writing multiple assignment statements.

Object Destructuring

// Without destructuring — repetitive
const user = { name: "Randhir", age: 25, role: "developer" };
const name = user.name;
const age  = user.age;
const role = user.role;

// With destructuring — clean and concise
const { name, age, role } = user;
console.log(name); // Randhir
console.log(age);  // 25

// With default values
const { name, age, country = "India" } = user;
console.log(country); // India — uses default since user.country is undefined

// With renaming
const { name: fullName } = user;
console.log(fullName); // Randhir

Array Destructuring

// Without destructuring
const colors = ["red", "green", "blue"];
const first  = colors[0];
const second = colors[1];

// With destructuring
const [first, second, third] = colors;
console.log(first);  // red
console.log(second); // green

// Skip elements with commas
const [, , third] = colors;
console.log(third); // blue

// Swap two variables without a temp variable
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1

Destructuring in Function Parameters

// Instead of this
function displayUser(user) {
  console.log(user.name + " is " + user.age + " years old");
}

// Do this — destructure directly in the parameter
function displayUser({ name, age }) {
  console.log(name + " is " + age + " years old");
}

displayUser({ name: "Randhir", age: 25 });
// Output: Randhir is 25 years old

5. Use the Spread Operator to Copy and Merge

The spread operator (...) was introduced in ES6 and is one of the most versatile tools in modern JavaScript. It expands an array or object into individual elements, which makes copying and merging data structures much simpler.

Copying an Array

// Without spread — both variables point to the same array (shallow reference)
const original = [1, 2, 3];
const copy = original; // NOT a copy — same reference
copy.push(4);
console.log(original); // [1, 2, 3, 4] — original is modified!

// With spread — creates a real independent copy
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // [1, 2, 3] — original is untouched
console.log(copy);     // [1, 2, 3, 4]

Merging Arrays

const fruits     = ["apple", "banana"];
const vegetables = ["carrot", "potato"];

// Merge two arrays into one
const food = [...fruits, ...vegetables];
console.log(food);
// ["apple", "banana", "carrot", "potato"]

// Add items while merging
const more = [...fruits, "mango", ...vegetables];
console.log(more);
// ["apple", "banana", "mango", "carrot", "potato"]

Copying and Merging Objects

const defaults = { theme: "dark", language: "en", fontSize: 14 };
const userPrefs = { theme: "light", fontSize: 16 };

// Merge — userPrefs values override defaults
const settings = { ...defaults, ...userPrefs };
console.log(settings);
// { theme: "light", language: "en", fontSize: 16 }

// Add a property to an object without mutating the original
const updatedUser = { ...user, role: "admin" };
// user is unchanged, updatedUser has the new role

The spread operator is particularly useful in React and Vue development where immutability matters — you never want to directly modify state objects or arrays, so spread gives you a clean way to create modified copies.

Bonus — Quick Reference Cheat Sheet

// 1. Always use strict equality
'10' === 10    // false — correct behaviour
'10' ==  10    // true  — misleading!

// 2. Six falsy values
Boolean(false)     // false
Boolean(0)         // false
Boolean("")        // false
Boolean(null)      // false
Boolean(undefined) // false
Boolean(NaN)       // false
Boolean([])        // true  — empty array is truthy!
Boolean({})        // true  — empty object is truthy!

// 3. Short-circuit defaults
let name = input || "Guest";        // fallback if falsy
let count = value ?? 0;             // fallback only if null/undefined
user && user.greet();               // call only if user exists

// 4. Destructuring
const { name, age } = user;         // object
const [first, second] = arr;        // array
const { name: alias } = user;       // rename while destructuring

// 5. Spread operator
const copy    = [...arr];           // copy array
const merged  = [...a, ...b];       // merge arrays
const newObj  = { ...obj, key: v }; // copy and add/override

Final Thought

These five patterns — strict equality, falsy values, short-circuit evaluation, destructuring, and the spread operator — are not just tips for writing shorter code. They reflect a deeper understanding of how JavaScript actually works under the hood. Once you internalise them, you will start spotting opportunities to use them naturally without thinking about it.

If there is one to start with today, make it === over ==. Enable an ESLint rule to enforce it, and within a week it will be automatic. The rest will follow.

Have a JavaScript tip or trick you think should be on this list? Share it with us via our contact page — we would love to hear what patterns you use every day.