5 Advanced JavaScript Tricks You Might Not Know

MentorAide
3 min readAug 5, 2024

--

1. Generators

Generators are functions that can be exited and later re-entered, maintaining their context and variable bindings across re-entrances.

Use Case: Implementing an iterator for custom object traversal.

function* objectEntries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}

const user = { name: 'John', age: 30, city: 'New York' };

for (let [key, value] of objectEntries(user)) {
console.log(`${key}: ${value}`);
}
// name: John
// age: 30
// city: New York

Why Use It: Generators provide a powerful tool for implementing custom iterators and simplifying asynchronous workflows.

2. Making Good Use of Console

Improve logging for debugging complex objects using console methods like console.table, console.group, and console.time.

// Basic logging
console.log('Simple log');
console.error('This is an error');
console.warn('This is a warning');

// Logging tabular data
const users = [
{ name: 'John', age: 30, city: 'New York' },
{ name: 'Jane', age: 25, city: 'San Francisco' },
];
console.table(users);

// Grouping logs
console.group('User Details');
console.log('User 1: John');
console.log('User 2: Jane');
console.groupEnd();

// Timing code execution
console.time('Timer');
for (let i = 0; i < 1000000; i++) {
// Some heavy computation
}
console.timeEnd('Timer');

Why Use It: Enhances the visibility and organization of debugging information, making it easier to diagnose and fix issues.

3. Structured Cloning with structuredClone

Deep clone objects using the new structuredClone method. This creates a deep copy of the object, ensuring that nested objects are also copied.

Use Case: Creating a deep copy of complex objects.

const obj = { 
a: 1,
b: { c: 2 },
date: new Date(),
arr: [1, 2, 3],
nestedArr: [{ d: 4 }]
};
const clonedObj = structuredClone(obj);

console.log(clonedObj);
// { a: 1, b: { c: 2 }, date: 2023-06-08T00:00:00.000Z, arr: [1, 2, 3], nestedArr: [{ d: 4 }] }
console.log(clonedObj === obj); // false
console.log(clonedObj.b === obj.b); // false
console.log(clonedObj.date === obj.date); // false
console.log(clonedObj.arr === obj.arr); // false
console.log(clonedObj.nestedArr[0] === obj.nestedArr[0]); // false

Why Use It: Provides a built-in, efficient way to perform deep cloning of objects, avoiding the pitfalls of manual deep copy implementations.

4. Self-Invoking Functions

Self-invoking functions, also known as Immediately Invoked Function Expressions (IIFE), are executed automatically after they are created.

Use Case: Encapsulating code to avoid polluting the global scope.

(function() {
const privateVar = 'This is private';
console.log('Self-invoking function runs immediately');
// Initialization code here
})();

// Private variables are not accessible from outside
// console.log(privateVar); // ReferenceError

Why Use It: Helps in modularizing code and preventing global namespace pollution, which is crucial for maintaining clean and organized codebases.

5. Dynamic Imports

Dynamic imports allow you to load modules asynchronously, which can improve performance by splitting code into smaller bundles that are loaded only when needed.

Use Case: Loading a heavy module only when a specific button is clicked.

document.getElementById('loadButton').addEventListener('click', async () => {
const module = await import('./heavyModule.js');
module.init();
});

// heavyModule.js
export function init() {
console.log('Heavy module loaded');
}

Why Use It: Enhances performance by reducing initial load times and allows for lazy loading of modules based on user interactions.

Happy coding! 🧙🔮

so that’s it for this article. I hope you all liked it and if you liked it then do not forget to tell us your thoughts in the comment section below.

Feel free to connect on LinkedIn

--

--

MentorAide
MentorAide

Responses (1)