Variables

· Seokhyeon Byun

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 with undefined, allows re-declaration
  • let: Block-scoped, hoisted but not initialized (TDZ), allows re-assignment
  • const: 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 properties
  • null: 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:

  1. First character: Must be a letter, underscore (_), or dollar sign ($)
  2. Cannot start with numbers: 1variable is invalid
  3. Subsequent characters: Can include letters, numbers, underscores, or dollar signs
  4. Case sensitive: myVariable and myvariable are different
  5. No length limit: Variable names can be any length
  6. No spaces allowed: Use camelCase or snake_case instead
  7. 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:

  1. Creates a new empty object
  2. Sets the object’s prototype to the constructor’s prototype
  3. Binds this to the new object
  4. Executes the constructor function
  5. Returns the new object (unless constructor explicitly returns another object)