← Back to Tutorials Chapter 4

Functions & Objects

Functions are reusable blocks of code. Objects store collections of key-value pairs. Together they form the backbone of JavaScript programs.

Function Declarations

A function declaration defines a named function that is hoisted to the top of its scope:

function greet(name) {
  return "Hello, " + name + "!";
}

console.log(greet("Alice")); // "Hello, Alice!"

Function Expressions

A function expression assigns a function to a variable. It is not hoisted:

const greet = function(name) {
  return "Hello, " + name + "!";
};

console.log(greet("Bob")); // "Hello, Bob!"

Arrow Functions

Arrow functions provide a concise syntax and do not have their own this binding:

const greet = (name) => {
  return `Hello, ${name}!`;
};

// Even shorter with implicit return
const greetShort = (name) => `Hello, ${name}!`;

console.log(greet("Charlie")); // "Hello, Charlie!"

Parameters and Arguments

Functions can have default parameters and rest parameters:

function multiply(a, b = 1) {
  return a * b;
}

function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

console.log(multiply(5));      // 5 (b defaults to 1)
console.log(sum(1, 2, 3, 4));  // 10
Tip: Arrow functions are ideal for short callbacks and methods that should not rebind this. Use function declarations for top-level functions that need hoisting.

Object Literals

Objects store data as key-value pairs using curly braces:

const person = {
  firstName: "Alice",
  lastName: "Johnson",
  age: 30,
  greet() {
    console.log(`Hi, I'm ${this.firstName}`);
  }
};

// Accessing properties
console.log(person.firstName); // "Alice"
console.log(person["lastName"]); // "Johnson"

person.greet(); // "Hi, I'm Alice"

Dot vs Bracket Notation

Use dot notation for known property names. Use bracket notation for dynamic keys or names with special characters:

const key = "age";
console.log(person[key]); // 30

const product = { "product-name": "Widget" };
console.log(product["product-name"]); // "Widget"

The this Keyword

this refers to the object that owns the executing code:

const car = {
  brand: "Toyota",
  describe() {
    console.log(`This is a ${this.brand}`);
  }
};

car.describe(); // "This is a Toyota"

Constructor Functions

Constructor functions create objects with shared structure (pre-ES6 pattern):

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const alice = new Person("Alice", 30);
console.log(alice.name); // "Alice"

ES6 Classes

Classes provide a cleaner syntax for constructor functions and inheritance:

class Animal {
  constructor(name, sound) {
    this.name = name;
    this.sound = sound;
  }

  speak() {
    console.log(`${this.name} says ${this.sound}`);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name, "Woof");
  }
}

const dog = new Dog("Rex");
dog.speak(); // "Rex says Woof"

Scope

JavaScript has three levels of scope:

// Global scope
let globalVar = "I'm global";

function test() {
  // Function scope
  let funcVar = "I'm local to this function";

  if (true) {
    // Block scope
    let blockVar = "I'm local to this block";
    console.log(globalVar); // Accessible
    console.log(funcVar);   // Accessible
  }
  // console.log(blockVar); // ReferenceError
}

Closures

A closure is a function that remembers its outer variables even after the outer function has returned:

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
JavaScript function execution context
Key Insight: Closures are powerful for data privacy and creating factory functions. Each call to createCounter() creates an independent closure with its own count.
Exercise: Write a createGreeter function that takes a greeting word and returns a new function. The returned function should accept a name and log the greeting followed by the name. Then use it to create a "Hello" greeter and a "Goodbye" greeter. Also write a Rectangle class with width, height, and an area() method.