1. Closures
Closures are functions that have access to variables from another function’s scope. This is often used for data privacy and creating function factories.
Example:
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log('Outer Variable: ' + outerVariable);
console.log('Inner Variable: ' + innerVariable);
};
}
const newFunction = outerFunction('outside');
newFunction('inside');
2. Promises and Asynchronous Programming
Promises are used to handle asynchronous operations. They represent a value which may be available now, or in the future, or never.
Example:
let myPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("Success!");
}, 1000);
});
myPromise.then(function(value) {
console.log(value);
});
3. Async/Await
async
and await
make it easier to work with promises. async
functions return a promise and await
can pause the execution of an async
function.
Example:
async function fetchData() {
try {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
fetchData();
4. Generators
Generators are functions that can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.
Example:
function* generatorFunction() {
yield 'First output';
yield 'Second output';
return 'done';
}
const generator = generatorFunction();
console.log(generator.next().value); // First output
console.log(generator.next().value); // Second output
console.log(generator.next().value); // done
5. Modules
JavaScript modules allow you to break your code into separate files. This makes it easier to manage and reuse code.
Example:
// file: math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// file: main.js
import { add, subtract } from './math.js';
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2
6. Proxy
Proxies allow you to intercept and customize operations performed on objects, such as getting, setting, and defining properties.
Example:
let target = {
message1: "hello",
message2: "everyone"
};
let handler = {
get: function(target, prop, receiver) {
return prop in target ? target[prop] : "Property not found";
}
};
let proxy = new Proxy(target, handler);
console.log(proxy.message1); // hello
console.log(proxy.message3); // Property not found
7. Symbols
Symbols are a new primitive type that is unique and immutable. They can be used to add unique property keys to an object that won’t collide with keys any other code might add to the object.
Example:
let sym = Symbol("unique");
let obj = {
[sym]: "value"
};
console.log(obj[sym]); // value
8. Map, Set, WeakMap, WeakSet
These are new collection types for storing data. Map
and Set
are similar to objects and arrays, but with some differences. WeakMap
and WeakSet
are similar, but do not prevent garbage collection of the keys or values.
Example:
let map = new Map();
map.set('key', 'value');
console.log(map.get('key')); // value
let set = new Set();
set.add(1);
set.add(1);
console.log(set.size); // 1 (values are unique)
let weakMap = new WeakMap();
let objKey = {};
weakMap.set(objKey, 'value');
console.log(weakMap.get(objKey)); // value
let weakSet = new WeakSet();
let objVal = {};
weakSet.add(objVal);
console.log(weakSet.has(objVal)); // true
These topics are essential for mastering advanced JavaScript and building complex applications. Each topic introduces powerful features that enhance the capabilities of JavaScript beyond the basics.