JavaScript: ES6+ Modern Features
Master the modern JavaScript syntax that makes code shorter, clearer, and more expressive.
Array Destructuring
Array destructuring unpacks values from an array into individual variables by position, removing the need for manual index access.
Array Destructuring
Variables on the left are matched to array positions on the right in order.
- Skip elements with a comma:
const [, second] = arr - Provide a default:
const [a = 0] = [], used when the element isundefined - Swap variables cleanly:
[a, b] = [b, a] - Works on any iterable: arrays, strings, Sets, Maps
Array Destructuring
Unpack by position, skip slots, set defaults, and swap variables in one line.
Press Run to execute the code and see output here.
Object Destructuring
Object destructuring extracts properties by name into local variables. You can rename them and provide defaults in the same expression.
Object Destructuring
Properties are matched by key name, order does not matter.
- Rename while destructuring:
const { name: userName } = user - Default value:
const { role = "guest" } = user - Combine rename and default:
const { role: r = "guest" } = user - Most common use: destructuring function parameters to pull out needed fields
Object Destructuring
Extract, rename, and set defaults all in one destructuring expression.
Press Run to execute the code and see output here.
Nested Destructuring
You can destructure nested objects and arrays by mirroring the structure on the left-hand side.
Nested Destructuring
Mirror the shape of the data on the left side to reach deeply nested values in one step.
- Each level of nesting adds another layer of braces or brackets on the left
- Apply defaults at any depth
- Keep it readable, if it gets complex, pull out intermediate variables instead
Nested Destructuring
Reach deep into an object or array in a single destructuring expression.
Press Run to execute the code and see output here.
Rest in Destructuring
The rest syntax (...) inside a destructuring pattern collects everything that was not explicitly extracted.
Rest in Destructuring
Use rest to extract a few properties and group the remainder into a new variable.
- Must be the last item in the destructuring pattern
- In arrays: collects remaining elements into a new array
- In objects: collects remaining properties into a new object
- Common use: separating props you need from the rest you will forward
Rest in Destructuring
Pull out what you need and collect the remainder with ...
Press Run to execute the code and see output here.
Spread Operator
The spread operator (...) expands an iterable or object into individual elements. It is the opposite of rest.
Spread Operator
Spread copies elements or properties out, use it to clone, merge, or pass arrays as arguments.
- Arrays: clone, concatenate, or insert elements without mutating the original
- Objects: shallow-clone or merge objects, later keys overwrite earlier ones
- Function calls: spread an array into individual positional arguments
- Spread creates a shallow copy, nested objects are still referenced, not deep-cloned
Spread in Arrays, Objects, and Function Calls
Expand iterables and objects to clone, merge, or pass as arguments.
Press Run to execute the code and see output here.
Rest Parameters
Rest parameters collect all remaining function arguments into a real array, replacing the old arguments object.
Rest Parameters
Rest parameters give variadic functions a clean, array-based way to handle any number of arguments.
- Syntax:
function fn(first, ...rest) - Must be the last parameter
- Unlike
arguments, rest is a true Array, use map, filter, reduce on it directly - Arrow functions do not have
arguments, rest parameters are the only option
Rest Parameters
Collect extra arguments into a real array, no more arguments object.
Press Run to execute the code and see output here.
Template Literals
Template literals use backticks (`) instead of quotes and support embedded expressions with ${} and multi-line strings without escape characters.
Template Literals
Template literals replace string concatenation with readable inline expressions.
- Embed any expression: variables, ternaries, function calls
- Multi-line strings without
\n, just press Enter inside the backticks - Tagged templates let a function process the template (used by styled-components, GraphQL)
- Nesting template literals is allowed for complex expressions
Template Literals
Embed expressions and write multi-line strings without concatenation or escape characters.
Press Run to execute the code and see output here.
Arrow Functions
Arrow functions provide a shorter syntax for writing functions and inheritthis from the surrounding scope instead of creating their own.
Arrow Functions
Arrow functions are ideal for short callbacks, they are concise and never rebind this.
- Single expression: implicit return, no braces needed:
x => x * 2 - Multiple statements: need braces and an explicit
return - No own
this,arguments, orsuper - Cannot be used as constructors (
new ArrowFn()throws)
Arrow Functions
Shorter syntax with implicit returns for single expressions, perfect for callbacks.
Press Run to execute the code and see output here.
Default Parameters
Default parameters assign a fallback value to a function parameter when the caller passesundefined or nothing at all.
Default Parameters
Default parameters eliminate the if (!arg) arg = default pattern inside function bodies.
- Triggered when the argument is
undefined, passingnulldoes NOT trigger the default - Default can be any expression, including a function call
- Later parameters can reference earlier ones:
function fn(a, b = a * 2) - Combine with destructuring defaults for flexible config objects
Default Parameters
Set safe fallbacks directly in the signature, no manual checks needed inside the body.
Press Run to execute the code and see output here.
Enhanced Object Literals
ES6 added three shorthand features for defining object literals: property shorthand, method shorthand, and computed property names.
Enhanced Object Literals
Less repetition and more expressive object definitions.
- Property shorthand:
{ name }instead of{ name: name } - Method shorthand:
{ greet() {} }instead of{ greet: function() {} } - Computed keys:
{ [varName]: value }, the key is evaluated at runtime
Enhanced Object Literals
Shorthand properties, shorthand methods, and computed keys in one example.
Press Run to execute the code and see output here.
for...of Loop
for...of iterates over the values of any iterable (arrays, strings, Sets, Maps, generators), in contrast tofor...in which iterates over keys.
for...of
Use for...of when you need the values, use for...in only when you specifically need the keys.
- Works on all iterables: Array, String, Set, Map, NodeList, generator
- Pair with
entries()to get both index and value:for (const [i, v] of arr.entries()) breakandcontinuework insidefor...of- Avoid
for...inon arrays, it iterates indices as strings and includes inherited properties
for...of Loop
Iterate values across arrays, strings, Sets, and any other iterable.
Press Run to execute the code and see output here.
let and const
let andconst are block-scoped alternatives tovar, introduced in ES6 to eliminate common scope and hoisting bugs.
let vs const vs var
Default to const, use let only when you need to reassign, avoid var in modern code.
const: block-scoped, must be initialised, cannot be reassigned (the binding is constant, not the value)let: block-scoped, can be reassigned, not hoisted to usable statevar: function-scoped, hoisted, leaks out of blocks, causes subtle bugs- Objects and arrays declared with
constcan still be mutated, only the variable binding is locked
let, const, and var
Block scope prevents leaks, const by default, let when reassignment is needed.
Press Run to execute the code and see output here.
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Reassignable | Yes | Yes | No |
| Hoisted | Yes (as undefined) | Yes (TDZ, unusable) | Yes (TDZ, unusable) |
| Re-declarable | Yes | No | No |
| Use today | Avoid | When needed | Default choice |
Knowledge Check
1. What does array destructuring do?
2. What is the output of: const { a = 10 } = {}; console.log(a);
3. What does the spread operator do when used with an array?
4. What do rest parameters collect?
5. Which feature lets you embed expressions inside a string using backticks?
6. What is property shorthand in ES6 object literals?
7. What is the key difference between for...of and for...in?