Modern JavaScript Syntax

Object Destructuring
Object destructuring allows you to extract properties from an object by their names. The variable names must match the property keys.
const user = {
id: 42,
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com'
};
// Extracting properties into variables
const { firstName, email } = user;
console.log(firstName); // "John"
console.log(email); // "john.doe@example.com"
Renaming Variables
If you want to create a variable with a different name than the object's property, you can use a colon (:
).
const { firstName: name, email: userEmail } = user;
console.log(name); // "John"
console.log(userEmail); // "john.doe@example.com"
Default Values
You can provide a default value for a property in case it doesn't exist in the object.
const settings = {
theme: 'dark',
fontSize: 14
};
const { theme, fontSize, layout = 'grid' } = settings;
console.log(theme); // "dark"
console.log(layout); // "grid" (since it wasn't in the object)
Array Destructuring
Array destructuring allows you to unpack values from an array based on their position (index).
const colors = ['Red', 'Green', 'Blue'];
// Extracting values by position
const [firstColor, secondColor] = colors;
console.log(firstColor); // "Red"
console.log(secondColor); // "Green"
Skipping Elements
You can skip elements in an array by using a comma without a variable name.
const rgb = [255, 128, 0];
const [red, , blue] = rgb;
console.log(red); // 255
console.log(blue); // 0
The Rest Pattern
You can use the rest syntax (...
) to collect all remaining elements into a new array.
const players = ['Alice', 'Bob', 'Charlie', 'David'];
const [winner, ...restOfPlayers] = players;
console.log(winner); // "Alice"
console.log(restOfPlayers); // ["Bob", "Charlie", "David"]
Practical Use Cases
Destructuring is incredibly useful, especially when working with functions.
Function Parameters
It's common to pass a configuration object to a function. Destructuring in the parameter list makes the code much cleaner.
// Instead of this:
function createUser(options) {
const name = options.name;
const age = options.age;
// ...
}
// You can do this:
function createUser({ name, age, email = 'default@email.com' }) {
console.log(`Creating user ${name}, age ${age} with email ${email}`);
}
createUser({ name: 'Jane', age: 30 });
// Output: Creating user Jane, age 30 with email default@email.com
Swapping Variables
Destructuring provides an elegant one-liner for swapping the values of two variables without needing a temporary variable.
let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a); // 20
console.log(b); // 10
Template literals
Template literals are an enhanced way to create strings in JavaScript. Instead of single ('
) or double ("
) quotes, you use backticks (`
) to enclose your string. This allows you to easily embed variables and create multi-line strings.
Variables and Expressions Inside Strings
Template literals allow you to embed variables or even full JavaScript expressions directly into a string using the ${expression}
syntax. This is called interpolation. It's much cleaner than traditional string concatenation using the +
operator.
Before: The Old Way (Concatenation)
const name = 'Alice';
const score = 98;
const message = 'Hello, ' + name + '! Your score is ' + score + '.';
console.log(message); // "Hello, Alice! Your score is 98."
After: With Template Literals
const name = 'Alice';
const score = 98;
const message = `Hello, ${name}! Your score is ${score}.`;
console.log(message); // "Hello, Alice! Your score is 98."
As you can see, the code is far more readable and less prone to errors from missing spaces or quotes.
Multi-line Strings
Creating strings that span multiple lines is effortless with template literals. Any line breaks you add inside the backticks are preserved in the final string.
Before: The Old Way (\n
)
const address = '123 Maple Street\n' +
'Anytown, USA 12345';
console.log(address);
// 123 Maple Street
// Anytown, USA 12345
After: With Template Literals
const address = `123 Maple Street
Anytown, USA 12345`;
console.log(address);
// 123 Maple Street
// Anytown, USA 12345
This method is much more intuitive, as the string in your code looks exactly like the final output.
Spread and Rest Operators:
The spread (...
) and rest (...
) operators in JavaScript use the same three-dot syntax but perform opposite actions. The spread operator expands an iterable (like an array or object) into individual elements, while the rest operator collects multiple elements into a single array.
The Spread Operator (...
)
The spread operator unpacks elements. Think of it as taking a container and spreading its contents out on a table. It's commonly used for combining, copying, or passing elements from an iterable.
Practical Examples:
Combining Arrays and Objects:
const fruits = ['apple', 'Banana']; const vegetables = ['carrot', Broccoli']; const food = [...fruits, ...vegetables]; console.log(food); // ['apple', 'Banana', 'carrot', 'Broccoli'] const user = { name: 'Alex', age: 30 }; const details = { city: 'New York', job: 'Developer' }; const userProfile = { ...user, ...details }; console.log(userProfile); // { name: 'Alex', age: 30, city: 'New York', job: 'Developer' }
Passing Arguments to a Function:
You can spread an array's elements as individual arguments into a function.
const numbers = [10, 5, 25, 15]; // Instead of Math.max(10, 5, 25, 15) const maxNumber = Math.max(...numbers); console.log(maxNumber); // 25
Spread Operator: Shallow Copy vs. Deep Copy
It's crucial to understand that the spread operator performs a shallow copy, not a deep copy.
Shallow Copy: This means it copies the top-level properties. However, if a property is a nested object or array, it only copies the reference (the memory address) to that nested structure, not the structure itself. Modifying the nested object in the copy will also affect the original.
Deep Copy: This creates a completely independent copy of the original object, including all nested structures.
Example of a Shallow Copy
Notice how changing the nested details
object in the copy
also changes it in the original
.
const original = {
name: 'Alice',
details: { age: 30, city: 'London' }
};
// Using spread to create a shallow copy
const copy = { ...original };
// Modifying a top-level property only affects the copy
copy.name = 'Bob';
// Modifying a nested property affects BOTH objects ๐ฑ
copy.details.age = 31;
console.log(original.name); // "Alice" (Unaffected)
console.log(copy.name); // "Bob" (Changed)
console.log(original.details.age); // 31 (Affected!)
console.log(copy.details.age); // 31 (Changed)
This happens because both original.details
and copy.details
point to the exact same object in memory. To create a deep copy, you would need other methods like JSON.parse(JSON.stringify(obj))
for simple cases, or a dedicated library like Lodash for more complex scenarios.
The Rest Operator (...
) ๐ฆ
The rest operator collects elements. It gathers an indefinite number of elements into a single array. This is incredibly useful in function parameters and destructuring.
Practical Examples:
Collecting Function Arguments: You can create functions that accept any number of arguments.
function sum(...numbers) { return numbers.reduce((total, num) => total + num, 0); } console.log(sum(1, 2)); // 3 console.log(sum(5, 10, 15)); // 30 console.log(sum(2, 4, 6, 8, 10)); // 30
Destructuring Arrays: You can use the rest operator to collect the "rest" of the elements from an array during destructuring.
const players = ['Alice', 'Bob', 'Charlie', 'David']; const [captain, coCaptain, ...team] = players; console.log(captain); // 'Alice' console.log(coCaptain); // 'Bob' console.log(team); // ['Charlie', 'David']
Now since both spread and Rest opearator look alike it will be difficult for freshers to indentify them :
The simplest rule of thumb is:
Spread (
...
) Unpacks: When you see...
being used to create something new (like in an array or object literal) or in a function call, it's spreading values out of an iterable.Rest (
...
) Collects: When you see...
in a function definition's parameters or on the left side of a destructuring assignment, it's collecting values into an array.
Comparison:
1. In Arrays & Destructuring
Spread Operator:
Used on the "right side" of an assignment to create a new array.
const arr1 = [1, 2];
const combined = [...arr1, 3, 4];
// Unpacks arr1 console.log(combined); // [1, 2, 3, 4]
Rest Operator:
Used on the "left side" of a destructuring assignment.
const numbers = [1, 2, 3, 4];
const [first, ...others] = numbers;
// Collects the rest console.log(first);
// 1 console.log(others); // [2, 3, 4]
Here, ...arr1
is spreading its values into a new array literal. In the other example, ...others
is a variable being declared to collect the rest of the values.
2. In Functions:
Spread Operator (In a Function Call)
Used when you call a function to pass an array's elements as individual arguments.
const numbers = [5, 10, 15];
// Spreads `numbers` into individual arguments
function add(a, b, c) {
return a + b + c;
}
console.log(add(...numbers)); // 30
Rest Operator (In a Function's Parameters):
Used when you define a function to gather an indefinite number of arguments into an array.
// Collects all arguments into the `numbers` array
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(5, 10, 15)); // 30
Here, add(...numbers)
is spreading the array into arguments 5, 10, 15
. In the other example, the sum
function's parameter ...numbers
is collecting all passed arguments into a single array.
Working with Map and Set:
Map
and Set
are modern JavaScript data structures that offer more specialized and powerful ways to organize data compared to traditional objects and arrays. A Map
is a collection of key-value pairs where keys can be of any data type, and a Set
is a collection of unique values.
Map: For Key-Value Pairs:
A Map
is similar to a plain JavaScript Object
, but it has one major advantage: keys can be any data type (including objects, functions, or numbers), not just strings. Maps also maintain the insertion order of their elements.
Key Methods:
set(key, value)
: Adds a new key-value pair.get(key)
: Retrieves the value for a given key.has(key)
: Checks if a key exists.delete(key)
: Removes a key-value pair.size
: A property that returns the number of entries.clear()
: Removes all entries.
Example Usage:
const user1 = { name: 'Alice' };
const user2 = { name: 'Bob' };
const userStatus = new Map();
userStatus.set(user1 , 'Online');
userStatus.set(user2 , 'Offline');
console.log(userStatus.get(user1)); //output: Online
console.log(userStatus.get(user2));//output : Offline
//orignal object remain unchanged no status prperty was added:
console.log(user1) //output : {name: 'Alice'}
This keeps data clean:
Notice that the original objects are unchanged. The status information is stored separately in our Map
.
Objects as Keys: The most important feature of Map
is that we used the actual user1
and user2
objects as the keys. A regular {}
object can't do this properly.
Set: For Unique Values
A Set
is a collection where each value must be unique. If you try to add a value that already exists, the Set
will simply ignore it. This makes Set
perfect for tasks like removing duplicate elements from an array. Like Map
, Set
also maintains insertion order.
Key Methods:
add(value)
: Adds a new value.has(value)
: Checks if a value exists.delete(value)
: Removes a value.size
: A property that returns the number of values.clear()
: Removes all values.
Example Usage
// Create a new Set
const tags = new Set();
// Use .add() to add values
tags.add('JavaScript');
tags.add('WebDev');
tags.add('Programming');
// Adding a duplicate value does nothing
tags.add('JavaScript');
console.log(tags); // Set(3) { 'JavaScript', 'WebDev', 'Programming' }
console.log(tags.size); // 3
console.log(tags.has('WebDev')); // true
tags.delete('Programming');
console.log(tags.has('Programming')); // false
Practical Use Case: Removing Duplicates from an Array
This is the most common use case for Set
.
const numbers = [1, 5, 2, 5, 3, 1, 4, 2];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 5, 2, 3, 4]
Subscribe to my newsletter
Read articles from Syed Wasif Hussain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
