ES6 JavaScript Features - Complete Guide

ES6 (ECMAScript 2015) introduced major improvements to JavaScript. This guide covers all essential ES6 features you need to know.

Let and Const #

let - Block-Scoped Variable #

// var is function-scoped
var x = 1;
if (true) {
  var x = 2;
  console.log(x);  // 2
}
console.log(x);  // 2

// let is block-scoped
let y = 1;
if (true) {
  let y = 2;
  console.log(y);  // 2
}
console.log(y);  // 1

const - Block-Scoped Constant #

const PI = 3.14159;
// PI = 3.14;  // Error: Assignment to constant

// Objects can be mutated
const person = { name: "Alice" };
person.name = "Bob";  // OK
person.age = 25;      // OK
// person = {};       // Error: Assignment to constant

// Arrays can be mutated
const arr = [1, 2, 3];
arr.push(4);     // OK
// arr = [];     // Error

Arrow Functions #

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

// Arrow function
const add = (a, b) => a + b;

// Single parameter
const square = x => x * x;

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

// Multiple lines
const sum = (a, b) => {
  const result = a + b;
  return result;
};

// This binding
const obj = {
  name: "Alice",
  greet: function() {
    setTimeout(() => {
      console.log(`Hello ${this.name}`);  // 'this' from obj
    }, 1000);
  }
};

Template Literals #

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

// String interpolation
const greeting = `Hello, ${name}!`;

// Multi-line strings
const message = `
  Name: ${name}
  Age: ${age}
  Next year: ${age + 1}
`;

// Expression evaluation
const price = 10;
const tax = 0.08;
console.log(`Total: $${(price * (1 + tax)).toFixed(2)}`);

// Tagged templates
function highlight(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<b>${values[i]}</b>` : '');
  }, '');
}

const user = "Alice";
const html = highlight`User: ${user}`;

Destructuring #

Array Destructuring #

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

// Basic
const [first, second] = arr;
console.log(first, second);  // 1 2

// Skip elements
const [a, , c] = arr;
console.log(a, c);  // 1 3

// Rest operator
const [head, ...tail] = arr;
console.log(head);  // 1
console.log(tail);  // [2, 3, 4, 5]

// Default values
const [x = 0, y = 0] = [1];
console.log(x, y);  // 1 0

// Swapping
let a = 1, b = 2;
[a, b] = [b, a];

Object Destructuring #

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

// Basic
const { name, age } = person;

// Rename variables
const { name: userName, age: userAge } = person;

// Default values
const { name, country = "USA" } = person;

// Nested destructuring
const user = {
  id: 1,
  profile: {
    name: "Alice",
    email: "alice@example.com"
  }
};

const { profile: { name, email } } = user;

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

greet(person);

Spread and Rest Operators #

Spread Operator (…) #

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

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

// Objects
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 };  // {a: 1, b: 2, c: 3, d: 4}

// Override properties
const updated = { ...obj1, b: 99 };  // {a: 1, b: 99}

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

Rest Operator #

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

sum(1, 2, 3, 4);  // 10

// With other parameters
function multiply(multiplier, ...numbers) {
  return numbers.map(n => n * multiplier);
}

multiply(2, 1, 2, 3);  // [2, 4, 6]

Default Parameters #

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

greet();                    // "Hello, Guest!"
greet("Alice");            // "Hello, Alice!"
greet("Bob", "Hi");        // "Hi, Bob!"

// Expression as default
function createUser(name, id = Date.now()) {
  return { name, id };
}

// Previous parameters in defaults
function calculate(x, y = x * 2) {
  return x + y;
}

Enhanced Object Literals #

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

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

// Shorthand methods
const obj = {
  greet() {
    return "Hello";
  },

  add(a, b) {
    return a + b;
  }
};

// Computed property names
const key = "dynamicKey";
const obj2 = {
  [key]: "value",
  [`${key}2`]: "value2"
};

Classes #

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

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

  static create(name, age) {
    return new Person(name, age);
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age);
    this.grade = grade;
  }

  study() {
    return `${this.name} is studying`;
  }
}

const student = new Student("Alice", 20, "A");

Modules #

Export #

// Named exports
export const PI = 3.14159;
export function add(a, b) {
  return a + b;
}

export class Calculator {
  multiply(a, b) {
    return a * b;
  }
}

// Export list
const a = 1;
const b = 2;
export { a, b };

// Export with rename
export { a as valueA, b as valueB };

// Default export
export default function() {
  console.log("Default export");
}

Import #

// Named imports
import { PI, add } from './math.js';

// Import with rename
import { PI as pi } from './math.js';

// Import all
import * as math from './math.js';
math.add(1, 2);

// Default import
import myFunction from './module.js';

// Mixed
import defaultExport, { namedExport } from './module.js';

Promises #

// Create promise
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success");
  }, 1000);
});

// Consume promise
promise
  .then(result => console.log(result))
  .catch(error => console.error(error));

// Promise.all
Promise.all([promise1, promise2, promise3])
  .then(results => console.log(results));

// Promise.race
Promise.race([promise1, promise2])
  .then(result => console.log(result));

Iterators and Generators #

Iterators #

const iterable = {
  [Symbol.iterator]() {
    let step = 0;
    return {
      next() {
        step++;
        if (step <= 3) {
          return { value: step, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (const value of iterable) {
  console.log(value);  // 1, 2, 3
}

Generators #

function* numberGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = numberGenerator();
console.log(gen.next().value);  // 1
console.log(gen.next().value);  // 2

// Infinite generator
function* infiniteNumbers() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

// Generator with parameters
function* range(start, end) {
  for (let i = start; i <= end; i++) {
    yield i;
  }
}

for (const num of range(1, 5)) {
  console.log(num);  // 1, 2, 3, 4, 5
}

Map and Set #

Map #

const map = new Map();

// Set values
map.set('name', 'Alice');
map.set('age', 25);
map.set(1, 'number key');

// Get values
console.log(map.get('name'));  // "Alice"

// Check existence
console.log(map.has('age'));  // true

// Size
console.log(map.size);  // 3

// Iterate
for (const [key, value] of map) {
  console.log(key, value);
}

// Delete
map.delete('age');

// Clear
map.clear();

Set #

const set = new Set();

// Add values
set.add(1);
set.add(2);
set.add(2);  // Duplicate ignored

// Check existence
console.log(set.has(1));  // true

// Size
console.log(set.size);  // 2

// Iterate
for (const value of set) {
  console.log(value);
}

// Array to Set (remove duplicates)
const arr = [1, 2, 2, 3, 3, 4];
const uniqueArr = [...new Set(arr)];  // [1, 2, 3, 4]

Symbol #

// Create symbols
const sym1 = Symbol();
const sym2 = Symbol('description');

// Symbols are unique
console.log(Symbol() === Symbol());  // false

// As object keys
const obj = {
  [Symbol('key')]: 'value'
};

// Well-known symbols
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next());  // {value: 1, done: false}

For…of Loop #

// Arrays
const arr = [1, 2, 3];
for (const num of arr) {
  console.log(num);
}

// Strings
const str = "hello";
for (const char of str) {
  console.log(char);
}

// Maps
const map = new Map([['a', 1], ['b', 2]]);
for (const [key, value] of map) {
  console.log(key, value);
}

// Sets
const set = new Set([1, 2, 3]);
for (const value of set) {
  console.log(value);
}

ES6 modernized JavaScript significantly. These features make code more concise, readable, and maintainable. Use them to write better JavaScript.