null vs undefined in JavaScript
- 1. undefined: Variable declared but not assigned.
- 2. null: Variable intentionally set to no value.
let a;
console.log(a); // undefined
let b = null;
console.log(b); // null
Summary:
undefined = automatic (I haven't given a value yet)
null = intentional (I specifically have no value)
var vs let
Scope
In JavaScript:
var is function-scoped. This means that a variable declared with var is accessible anywhere within the function in which it is declared, regardless of block boundaries (like { ... }).
let is block-scoped. This means that a variable declared with let is only accessible within the block (e.g., inside { ... }) where it is defined.
Example:
function hi() {
{
let a = 10;
var b = 20; // 'b' is function-scoped, not block-scoped
}
console.log(b); // 20 - accessible, because 'b' is function-scoped
console.log(a); // ReferenceError: a is not defined - 'a' is block-scoped
}
hi();
b is accessible outside the block because var ignores the block and only cares about the function scope.
a is not accessible outside the block because let restricts its visibility to the block where it is defined.
Hoisting
- Both var and let are hoisted to the top of their scope. However, var is initialized with undefined during hoisting, so you can reference it before its declaration (but its value will be undefined).
- let is not initialized during hoisting. If you try to access it before its declaration, you get a ReferenceError due to the "temporal dead zone."
Example:
console.log(a); // undefined - 'a' is hoisted and initialized
console.log(b); // ReferenceError: Cannot access 'b' before initialization
var a = 1;
let b = 2;
Redeclaration
var can be redeclared within the same scope without error.
let cannot be redeclared within the same scope. Attempting to do so results in a SyntaxError.
let a = 2;
let a = 3; // SyntaxError: Identifier 'a' has already been declared
var b = 2;
var b = 3; // No error, 'b' is simply reassigned
Summary:
- var is function-scoped.
- let is block-scoped.
- Variables declared with var inside a block are still accessible anywhere in the function.
- Variables declared with let inside a block are only accessible within that block.
- var is hoisted and initialized as undefined.
- let is hoisted but not initialized; accessing it before declaration throws a ReferenceError due to the temporal dead zone.
- var: can be redeclared in the same scope
- let: cannot be redeclared in the same scope (will throw a SyntaxError)
Using let leads to safer, clearer, and more maintainable code compared to var.
Weird Implicit Conversion (Type Coercion)
JavaScript uses implicit type coercion to automatically convert between strings and numbers during operations, which can lead to unexpected results—especially with +, -, or *. To avoid surprises, use explicit type coercion to control how your values are converted.
const a = "3";
const b = 2;
console.log(a + b); // "32" (implicit coercion: string concatenation)
console.log(a - b); // 1 (implicit coercion: numeric subtraction)
console.log(a * b); // 6 (implicit coercion: numeric multiplication)
// Avoid surprises with explicit type coercion:
console.log(parseInt(a) + b); // 5 (explicit coercion: numeric addition)
console.log(a + b.toString()); // "32" (explicit coercion: string concatenation)
Tip:
Use parseInt() or Number() for explicit numeric conversion, and toString() for explicit string conversion, so your results are always clear and predictable.
What the Heck is NaN in JavaScript?
Ever seen NaN in JavaScript? It stands for "Not-a-Number"—but it’s actually a special value of type number!
const a = "hello";
const b = parseInt(a); // NaN
console.log(typeof NaN); // "number" (wait, what?)
console.log(NaN == NaN); // false (seriously?)
- NaN means a failed numeric conversion.
- Weirdly, NaN is a number, but it’s not equal to itself!
How do you check for NaN?
console.log(isNaN(b)); // true
Tip:
Always use isNaN() to check for NaN—it’s the only reliable way!
Equality and Type Coercion (== vs === or != vs !==) in JavaScript
In JavaScript, == and != compare values with type coercion, converting types if needed. === and !== compare both value and type, so no conversion happens.
// Equality
console.log(0 == false); // true
console.log(0 === false); // false
console.log("" == 0); // true
console.log("" === 0); // false
console.log("" == false); // true
console.log("" === false); // false
console.log("1" == 1); // true
console.log("1" === 1); // false
// Not Equality
console.log(0 != false); // false
console.log(0 !== false); // true
console.log("" != 0); // false
console.log("" !== 0); // true
console.log("" != false); // false
console.log("" !== false); // true
console.log("1" != 1); // false
console.log("1" !== 1); // true
Tip:
Prefer === and !== for clear and predictable comparisons.
Top comments (0)