Updated Jul 17, 2026

07 - Modern JavaScript (ES6+)

📋 Jump to Takeaways

🎁 Both || and ?? give you a fallback value. But swap one for the other and a valid 0 or "" can silently disappear. When does that bite you?

Template Literals

Create strings with embedded expressions:

// Old way: string concatenation
const name = "Alice";
const age = 25;
const messageOld = "Hello, " + name + "! You are " + age + " years old.";
console.log(messageOld);  // "Hello, Alice! You are 25 years old."

// Template literals (ES6+)
const message = `Hello, ${name}! You are ${age} years old.`;
console.log(message);  // "Hello, Alice! You are 25 years old."

// Multi-line strings
const html = `
  <div class="card">
    <h2>${name}</h2>
    <p>Age: ${age}</p>
  </div>
`;

// Expressions inside ${}
const price = 19.99;
const tax = 0.08;
const total = `Total: $${(price * (1 + tax)).toFixed(2)}`;
console.log(total);  // "Total: $21.59"

Destructuring

Extract values from arrays and objects:

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

// Object destructuring
const person = { name: "Alice", age: 25, city: "NYC" };
const { name, age } = person;
console.log(name);  // "Alice"

Rename properties and set defaults as you destructure:

const person = { name: "Alice", age: 25 };

// Rename during destructuring
const { name: personName } = person;
console.log(personName);  // "Alice"

// Default value for a missing key
const { country = "USA" } = person;
console.log(country);  // "USA"

Destructuring also works on nested objects and function parameters:

const user = {
  id: 1,
  profile: {
    name: "Alice",
    email: "[email protected]"
  }
};

// Nested destructuring
const { profile: { name, email } } = user;
console.log(name);   // "Alice"
console.log(email);  // "[email protected]"

// In function parameters
function greet({ name, age }) {
  console.log(`Hello ${name}, you are ${age}`);
}

greet({ name: "Alice", age: 25 });  // "Hello Alice, you are 25"

Spread and Rest Operators

Expand arrays and objects:

// Arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// Combine arrays
const combined = [...arr1, ...arr2];
console.log(combined);  // [1, 2, 3, 4, 5, 6]

// Copy array
const copy = [...arr1];

// Add items
const extended = [0, ...arr1, 4];
console.log(extended);  // [0, 1, 2, 3, 4]

// Objects
const person = { name: "Alice", age: 25 };
const address = { city: "NYC", country: "USA" };

// Merge objects
const full = { ...person, ...address };
console.log(full);
// { name: "Alice", age: 25, city: "NYC", country: "USA" }

// Override properties
const updated = { ...person, age: 26 };
console.log(updated);  // { name: "Alice", age: 26 }

// Function arguments
const numbers = [1, 5, 3, 9, 2];
console.log(Math.max(...numbers));  // 9

Rest Operator

Collect multiple elements into an array:

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

console.log(sum(1, 2, 3));        // 6
console.log(sum(1, 2, 3, 4, 5));  // 15

// Mix with regular parameters
function introduce(greeting, ...names) {
  console.log(`${greeting} ${names.join(", ")}`);
}

introduce("Hello", "Alice", "Bob", "Charlie");
// "Hello Alice, Bob, Charlie"

// Array destructuring
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first);  // 1
console.log(second); // 2
console.log(rest);   // [3, 4, 5]

// Object destructuring
const person = { name: "Alice", age: 25, city: "NYC", country: "USA" };
const { name, ...details } = person;
console.log(name);     // "Alice"
console.log(details);  // { age: 25, city: "NYC", country: "USA" }

Arrow Functions

Concise function syntax:

// Traditional function
function add(a, b) {
  return a + b;
}

// Arrow function, explicit return
const addArrow = (a, b) => {
  return a + b;
};

// Implicit return (no braces)
const addShort = (a, b) => a + b;

// Single parameter (no parentheses needed)
const double = n => n * 2;

// No parameters (parentheses required)
const greet = () => "Hello!";

// Returning an object literal (wrap in parentheses)
const makePerson = (name, age) => ({ name, age });

console.log(add(2, 3), addArrow(2, 3), addShort(2, 3)); // 5 5 5
console.log(double(4), greet());                        // 8 "Hello!"
console.log(makePerson("Alice", 25));                   // { name: "Alice", age: 25 }

Default Parameters

// Old way
function greet(name) {
  name = name || "Guest";
  return `Hello, ${name}!`;
}

// Modern way
function greet(name = "Guest") {
  return `Hello, ${name}!`;
}

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

// With expressions
function createArray(length = 10, fill = 0) {
  return Array(length).fill(fill);
}

console.log(createArray());      // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
console.log(createArray(3, 5));  // [5, 5, 5]

Enhanced Object Literals

const name = "Alice";
const age = 25;

// Old way: repeat names, function keyword for methods
const personVerbose = {
  name: name,
  age: age,
  greet: function() {
    console.log("Hello");
  }
};

// Modern way: shorthand properties and methods
const person = {
  name,
  age,
  greet() {
    console.log("Hello");
  }
};
console.log(person.name);  // "Alice"
person.greet();            // "Hello"

Property names can also be computed at creation time:

const key = "favoriteColor";
const profile = {
  name: "Alice",
  [key]: "blue"
};
console.log(profile.favoriteColor);  // "blue"

Classes

Object-oriented programming in JavaScript:

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

  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }

  haveBirthday() {
    this.age++;
    console.log(`Happy birthday! Now ${this.age}`);
  }
}

const alice = new Person("Alice", 25);
alice.greet();         // "Hello, I'm Alice"
alice.haveBirthday();  // "Happy birthday! Now 26"

// Inheritance
class Student extends Person {
  constructor(name, age, major) {
    super(name, age);  // call parent constructor
    this.major = major;
  }

  study() {
    console.log(`${this.name} is studying ${this.major}`);
  }
}

const bob = new Student("Bob", 20, "Computer Science");
bob.greet();   // "Hello, I'm Bob" (inherited)
bob.study();   // "Bob is studying Computer Science"

// Static methods
class MathUtils {
  static add(a, b) {
    return a + b;
  }

  static multiply(a, b) {
    return a * b;
  }
}

console.log(MathUtils.add(2, 3));      // 5
console.log(MathUtils.multiply(4, 5)); // 20

// Getters and setters
class Circle {
  constructor(radius) {
    this.radius = radius;
  }

  get area() {
    return Math.PI * this.radius ** 2;
  }

  set area(value) {
    this.radius = Math.sqrt(value / Math.PI);
  }
}

const circle = new Circle(5);
console.log(circle.area);    // 78.54...
circle.area = 314.16;
console.log(circle.radius);  // ~10

Modules

Split code across files:

// math.js, export functions
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

export const PI = 3.14159;

// Default export
export default function multiply(a, b) {
  return a * b;
}

// main.js, import functions
import multiply, { add, subtract, PI } from "./math.js";

console.log(add(2, 3));       // 5
console.log(multiply(2, 3));  // 6
console.log(PI);              // 3.14159

// Import everything
import * as MathUtils from "./math.js";
console.log(MathUtils.add(2, 3));       // 5
console.log(MathUtils.default(2, 3));   // 6

// Rename imports
import { add as sum } from "./math.js";
console.log(sum(2, 3));  // 5

Optional Chaining

Safely access nested properties:

const user = {
  name: "Alice",
  address: {
    city: "NYC"
  }
};

// Old way, manual checks
const country = user && user.address && user.address.country;

// Optional chaining
const country = user?.address?.country;  // undefined (no error)
const city = user?.address?.city;        // "NYC"

// With arrays
const users = [{ name: "Alice" }];
const secondUser = users?.[1]?.name;  // undefined (no error)

// With functions
const result = user.someMethod?.();  // undefined if method doesn't exist

Nullish Coalescing

Provide default values for null/undefined:

// Old way, ||
const value = someValue || "default";
// Problem: 0, "", false are all replaced

// Nullish coalescing, ??
const value = someValue ?? "default";
// Only replaces null and undefined

const count = 0;
console.log(count || 10);   // 10 (0 is falsy)
console.log(count ?? 10);   // 0 (0 is not null/undefined)

const name = "";
console.log(name || "Guest");   // "Guest" ("" is falsy)
console.log(name ?? "Guest");   // "" ("" is not null/undefined)

Array Methods (ES6+)

const numbers = [1, 2, 3, 4, 5];

// find, first matching item
const found = numbers.find(n => n > 3);
console.log(found);  // 4

// findIndex, index of first match
const index = numbers.findIndex(n => n > 3);
console.log(index);  // 3

// includes, check if exists
console.log(numbers.includes(3));  // true

// flat, flatten nested arrays
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat());     // [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(2));    // [1, 2, 3, 4, 5, 6]

// flatMap, map then flatten
const words = ["hello world", "foo bar"];
const letters = words.flatMap(word => word.split(" "));
console.log(letters);  // ["hello", "world", "foo", "bar"]

Key Takeaways

  • Template literals (`) make string interpolation easy
  • Destructuring extracts values from arrays and objects
  • Spread (...) expands, rest (...) collects
  • Arrow functions provide concise syntax
  • Classes add object-oriented programming
  • Modules split code across files with import/export
  • Optional chaining (?.) safely accesses nested properties
  • Nullish coalescing (??) provides defaults for null/undefined only
  • Modern array methods make data manipulation easier

🎁 You've learned every piece of the language. Ready to wire them into one real app, a notes tool that saves your data even after you close the tab?

📝 Ready to test your knowledge?

Answer the quiz below to mark this lesson complete.

Spot something off? Report an issue
© 2026 ByteLearn.dev. Free courses for developers. · Privacy