Variables
Note: This post is based on my old programming study notes when I taught myself.
Variable Declarations
JavaScript has three ways to declare variables:
var
Declaration
- Scope: Function-scoped or globally-scoped
- Hoisting: Hoisted and initialized with
undefined
- Re-declaration: Allowed
- Re-assignment: Allowed
var name = "John";
var name = "Jane"; // Re-declaration allowed
name = "Bob"; // Re-assignment allowed
function example() {
var x = 1;
if (true) {
var x = 2; // Same variable (function-scoped)
console.log(x); // 2
}
console.log(x); // 2
}
let
Declaration
- Scope: Block-scoped
- Hoisting: Hoisted but not initialized (Temporal Dead Zone)
- Re-declaration: Not allowed in same scope
- Re-assignment: Allowed
let age = 25;
// let age = 30; // SyntaxError: Identifier 'age' has already been declared
age = 30; // Re-assignment allowed
function example() {
let y = 1;
if (true) {
let y = 2; // Different variable (block-scoped)
console.log(y); // 2
}
console.log(y); // 1
}
const
Declaration
- Scope: Block-scoped
- Hoisting: Hoisted but not initialized (Temporal Dead Zone)
- Re-declaration: Not allowed
- Re-assignment: Not allowed (but objects/arrays can be mutated)
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable
const person = { name: "John" };
person.name = "Jane"; // Allowed - mutating object properties
// person = {}; // TypeError: Assignment to constant variable
Interview Question: What’s the difference between var
, let
, and const
?
Answer:
var
: Function-scoped, hoisted withundefined
, allows re-declarationlet
: Block-scoped, hoisted but not initialized (TDZ), allows re-assignmentconst
: Block-scoped, hoisted but not initialized (TDZ), immutable binding
Variable Scopes
- Global scope: Variables accessible throughout the program
- Function scope: Variables accessible within the function
- Block scope: Variables accessible within the block
{}
- Module scope: Variables accessible within the module file
JavaScript Data Types
Number Type
JavaScript has only one number type that represents both integers and floating-point numbers.
// Integer examples
let age = 25;
let temperature = -10;
// Floating-point examples
let price = 19.99;
let pi = 3.14159;
// Special numeric values
let infinity = Infinity;
let negInfinity = -Infinity;
let notANumber = NaN;
// Scientific notation
let bigNumber = 2.5e6; // 2,500,000
let smallNumber = 1e-6; // 0.000001
Important Notes:
- JavaScript uses IEEE 754 double-precision floating-point format
- Maximum safe integer:
Number.MAX_SAFE_INTEGER
(2^53 - 1) - For larger integers, use
BigInt
Reference: Number Global Object
String Type
A sequence of characters representing text values.
// Different ways to create strings
let singleQuote = "Hello World";
let doubleQuote = "Hello World";
let templateLiteral = `Hello World`;
// Template literals with variables
let name = "John";
let age = 30;
let message = `My name is ${name} and I'm ${age} years old`;
// String methods
let text = "JavaScript";
console.log(text.length); // 10
console.log(text.toUpperCase()); // "JAVASCRIPT"
console.log(text.substring(0, 4)); // "Java"
Key Features:
- Immutable - string methods return new strings
- Template literals (backticks) allow variable interpolation
- Rich set of built-in methods for manipulation
Boolean Type
Represents logical values: true
or false
.
let isStudent = true;
let isGraduated = false;
// Boolean conversion - Falsy values
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(false)); // false
// Everything else is truthy
console.log(Boolean(1)); // true
console.log(Boolean("hello")); // true
console.log(Boolean([])); // true
console.log(Boolean({})); // true
Refer: MDN Falsy
Falsy Values: false
, 0
, -0
(negative zero), 0n
(bigint zero), ""
(empty string), null
, undefined
, NaN
(not a number)
Truthy Values: Everything else
Null and Undefined Types
Null
Represents an intentional absence of any object value.
let data = null; // Explicitly set to null
console.log(typeof null); // "object" (known bug in JavaScript)
console.log(data === null); // true
console.log(data == undefined); // true (loose equality)
console.log(data === undefined); // false (strict equality)
Key Points:
- Must be explicitly assigned
typeof null
returns"object"
(historical bug that can’t be fixed)- Represents “no value” or “empty value”
Undefined
Represents a variable that has been declared but not assigned a value.
let x; // Declared but not assigned
console.log(x); // undefined
console.log(typeof x); // "undefined"
function test(param) {
console.log(param); // undefined if no argument passed
}
let obj = {};
console.log(obj.nonExistentProperty); // undefined
Key Points:
- Default value for uninitialized variables
- Returned when accessing non-existent object properties
- Returned by functions that don’t explicitly return a value
Interview Question: What’s the difference between null
and undefined
?
Answer:
undefined
: Variable declared but not assigned, or accessing non-existent propertiesnull
: Intentionally assigned to represent “no value”typeof null
:"object"
(bug),typeof undefined
:"undefined"
Type Coercion and Comparison
Loose vs Strict Equality
- Strict equality uses three equal symbols
- Strict inequality uses one exclamation mark and two equal symbols
// Loose equality (==) performs type coercion
console.log(5 == "5"); // true
console.log(null == undefined); // true
console.log(0 == false); // true
console.log("" == false); // true
// Strict equality (===) no type coercion
console.log(5 === "5"); // false
console.log(null === undefined); // false
console.log(0 === false); // false
console.log("" === false); // false
Best Practice: Always use strict equality (===
) and strict inequality (!==
) to avoid unexpected behavior.
Type Checking
// Using typeof operator
console.log(typeof 42); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (bug)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function () {}); // "function"
// Better array checking
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
Interview Question: How do you check if a variable is an array in JavaScript?
Answer: Use Array.isArray()
method, not typeof
(which returns “object” for arrays).
Memory Management and Garbage Collection
JavaScript automatically manages memory through garbage collection.
How Garbage Collection Works
// Memory is allocated when objects are created
let obj = { name: "John", age: 30 }; // Memory allocated
// Memory is freed when objects are no longer referenced
obj = null; // Original object becomes eligible for garbage collection
// Circular references (potential memory leaks in older browsers)
function createCircularReference() {
let obj1 = {};
let obj2 = {};
obj1.ref = obj2;
obj2.ref = obj1;
// Modern browsers handle this, but be aware
}
Key Points:
- Automatic memory allocation and deallocation
- Uses mark-and-sweep algorithm in modern browsers
- Circular references are handled by modern garbage collectors
- Be careful with closures holding references to large objects
Reference: Memory Management Documentation
Variable Naming Rules
JavaScript has specific rules for naming variables:
- First character: Must be a letter, underscore (_), or dollar sign ($)
- Cannot start with numbers:
1variable
is invalid - Subsequent characters: Can include letters, numbers, underscores, or dollar signs
- Case sensitive:
myVariable
andmyvariable
are different - No length limit: Variable names can be any length
- No spaces allowed: Use camelCase or snake_case instead
- Readability matters: Choose descriptive names
// Valid variable names
let userName = "John";
let _privateVar = 42;
let $element = document.getElementById("test");
let user2 = "Jane";
// Invalid variable names
// let 2user = "Invalid"; // Cannot start with number
// let user name = "Invalid"; // No spaces allowed
// let user-name = "Invalid"; // Hyphens not allowed
Advanced Variable Concepts
NaN (Not-a-Number)
NaN
is a special numeric value representing an invalid number.
// Common situations that return NaN
console.log(parseInt("hello")); // NaN
console.log(Number(undefined)); // NaN
console.log(Math.sqrt(-1)); // NaN
console.log(0 / 0); // NaN
console.log("text" * 2); // NaN
// Check for NaN
console.log(isNaN(NaN)); // true
console.log(Number.isNaN(NaN)); // true (more reliable)
console.log(NaN === NaN); // false (NaN is not equal to itself)
Key Points:
NaN
is the only value in JavaScript that is not equal to itself- Use
Number.isNaN()
for reliable NaN checking - Result of failed number conversion or invalid math operations
Arrays
Arrays are ordered collections that can hold multiple data types.
// Array creation
let fruits = ["apple", "banana", "orange"];
let mixed = [1, "hello", true, null, { name: "John" }];
let empty = new Array(5); // Creates array with 5 empty slots
// Array properties and methods
console.log(fruits.length); // 3
fruits.push("grape"); // Add to end
fruits.pop(); // Remove from end
fruits.unshift("mango"); // Add to beginning
fruits.shift(); // Remove from beginning
// Important array methods for interviews
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map((x) => x * 2); // [2, 4, 6, 8, 10]
let evens = numbers.filter((x) => x % 2 === 0); // [2, 4]
let sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15
// Array destructuring
let [first, second, ...rest] = fruits;
console.log(first); // First element
console.log(rest); // Remaining elements as array
Objects
Objects are collections of key-value pairs (properties).
// Object literal syntax
const person = {
name: "John",
age: 30,
city: "New York",
greet: function () {
return `Hello, I'm ${this.name}`;
},
};
// Accessing properties
console.log(person.name); // Dot notation
console.log(person["age"]); // Bracket notation
console.log(person.greet()); // Method call
// Object destructuring
const { name, age } = person;
console.log(name); // "John"
// Dynamic property names
const key = "profession";
const developer = {
name: "Jane",
[key]: "Software Engineer", // Dynamic key
};
// Object vs JSON
// Object literal: {name: "John", age: 30}
// JSON: {"name": "John", "age": 30} // Keys must be double-quoted
Interview Question: What’s the difference between Object literal and JSON?
Answer: Object literals use JavaScript syntax and can contain functions, while JSON requires double-quoted keys and only supports data (no functions).
Reference vs Value Types
Understanding how JavaScript handles different data types in memory.
// Primitive types (passed by value)
let a = 5;
let b = a; // b gets a copy of a's value
a = 10;
console.log(b); // 5 (unchanged)
// Objects (passed by reference)
let obj1 = { count: 5 };
let obj2 = obj1; // obj2 references the same object
obj1.count = 10;
console.log(obj2.count); // 10 (changed because same reference)
// Array reference example
let arr1 = [1, 2, 3];
let arr2 = arr1; // Same reference
let arr3 = [...arr1]; // New array with copied values
arr1.push(4);
console.log(arr2); // [1, 2, 3, 4] (affected)
console.log(arr3); // [1, 2, 3] (not affected)
Interview Question: Explain the difference between pass by value and pass by reference in JavaScript.
Answer:
- Primitives (string, number, boolean, null, undefined, symbol) are passed by value
- Objects (including arrays and functions) are passed by reference
- Modifying a primitive parameter doesn’t affect the original, but modifying an object does
Template Literals
Modern string syntax with embedded expressions and multi-line support.
// Basic template literal
const name = "John";
const age = 30;
const message = `Hello, I'm ${name} and I'm ${age} years old.`;
// Multi-line strings
const multiLine = `
This is line 1
This is line 2
This is line 3
`;
// Expression evaluation
const a = 10;
const b = 20;
const result = `The sum of ${a} and ${b} is ${a + b}`;
// Tagged templates (advanced)
function highlight(strings, ...values) {
return strings.reduce((result, string, i) => {
return result + string + (values[i] ? `<mark>${values[i]}</mark>` : "");
}, "");
}
const highlighted = highlight`Hello ${name}, you are ${age} years old!`;
The new
Operator and this
Keyword
Understanding object creation and context binding.
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function () {
return `Hello, I'm ${this.name}`;
};
}
// Using new operator
const john = new Person("John", 30);
console.log(john.greet()); // "Hello, I'm John"
// What happens without 'new'?
const jane = Person("Jane", 25); // DON'T DO THIS
console.log(jane); // undefined
console.log(window.name); // "Jane" (global pollution)
// this context examples
const obj = {
name: "Object",
regular: function () {
return this.name; // 'this' refers to obj
},
arrow: () => {
return this.name; // 'this' refers to global/window
},
};
console.log(obj.regular()); // "Object"
console.log(obj.arrow()); // undefined (or global context)
Interview Question: What does the new
operator do in JavaScript?
Answer:
- Creates a new empty object
- Sets the object’s prototype to the constructor’s prototype
- Binds
this
to the new object - Executes the constructor function
- Returns the new object (unless constructor explicitly returns another object)