Let and Const are block-scoped variable declarations. They are preferred over var, which is function-scoped.
let x = 10; x = 20; // Allowed const y = 30; y = 40; // Error: Assignment to constant variable.
Arrow functions provide a shorter syntax for writing functions and also lexically bind the this keyword.
const sumArrow = (a, b) => a + b; console.log(sumArrow(2, 3)); // Output: 5
Template literals allow for string interpolation and multi-line strings, improving readability.
const name = 'Alice'; const greeting = \`Hello, \${name}! Welcome to JavaScript.\`; console.log(greeting); // Output: Hello, Alice! Welcome to JavaScript.
Destructuring allows you to unpack values from arrays or properties from objects into distinct variables.
const arr = [1, 2, 3]; const [a, b] = arr; console.log(a, b); // Output: 1 2 const person = { name: 'Alice', age: 30 }; const { name, age } = person; console.log(name, age); // Output: Alice 30
Spread allows you to spread elements of an array or object. Rest allows you to collect multiple elements into a single array or object.
// Spread in Arrays const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5]; console.log(arr2); // Output: [1, 2, 3, 4, 5] // Rest in Function Parameters function sum(...numbers) { return numbers.reduce((a, b) => a + b, 0); } console.log(sum(1, 2, 3, 4)); // Output: 10
ES6 introduced classes, providing a more structured way to work with objects and inheritance.
class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { console.log(\`Hello, my name is \${this.name}\`); } } class Student extends Person { constructor(name, age, grade) { super(name, age); this.grade = grade; } study() { console.log(\`\${this.name} is studying.\`); } } const student = new Student('Alice', 20, 'A'); student.greet(); // Output: Hello, my name is Alice student.study(); // Output: Alice is studying.
Generators are functions that can be paused and resumed, and they allow you to define an iterative process.
function* generatorExample() { yield 1; yield 2; yield 3; } const gen = generatorExample(); console.log(gen.next().value); // Output: 1 console.log(gen.next().value); // Output: 2 console.log(gen.next().value); // Output: 3
ES6 modules allow you to split code into multiple files and import/export values between them.
// module.js export const greeting = 'Hello, World!'; export function greet(name) { return \`\${greeting} My name is \${name}\`; } // app.js import { greeting, greet } from './module.js'; console.log(greeting); // Output: Hello, World! console.log(greet('Alice')); // Output: Hello, World! My name is Alice
Set: A collection of unique values. Map: A collection of key-value pairs, where keys can be of any data type.
// Set const set = new Set([1, 2, 3, 3]); set.add(4); console.log(set); // Output: Set { 1, 2, 3, 4 } // Map const map = new Map(); map.set('name', 'Alice'); map.set('age', 30); console.log(map.get('name')); // Output: Alice
Symbols are unique and immutable primitive values that can be used as object property keys.
const symbol = Symbol('id'); const user = { [symbol]: 123, }; console.log(user[symbol]); // Output: 123
A Proxy allows you to define custom behavior for fundamental operations (e.g., property lookup, assignment, etc.).
const person = { name: 'Alice', age: 25, }; const handler = { get: function (target, prop) { if (prop === 'age') { return 'Age is confidential'; } return prop in target ? target[prop] : 'Property not found'; }, }; const proxyPerson = new Proxy(person, handler); console.log(proxyPerson.name); // Output: Alice console.log(proxyPerson.age); // Output: Age is confidential console.log(proxyPerson.city); // Output: Property not found