JavaScript Tricks for Efficient Coding: Mastering Techniques Every Developer Should Know
Table of contents
- Destructuring Assignment
- Spread Syntax
- Closures
- Function Composition
- Event Delegation
- Web Workers
- Memoization for Performance Optimization
- Advanced Array Methods
- Shuffling an Array
- Optional Chaining and Nullish Coalescing
- Using Function.prototype.bind():
- Partial Function Application
- Currying Functions
- Wrapping Up
JavaScript, the foundational technology of this aspect, powers the interactivity and gives functionality to websites and applications in the dynamic world of web development. This tool comes with a huge set of features and its essential tricks and techniques will do the magic in terms of better readability, efficiency, and performance of the code. In this post, we shall look at some of these key JavaScript tricks including Destructuring Assignment, Spread Syntax, Closures, Function Composition, Event Delegation, and Web Workers.
Destructuring Assignment
Destructuring assignment syntax is the expression in JavaScript that provides us with the facility of breaking down values from arrays or properties from objects into separate variables. It provides a way to easily access and work with information stored in arrays and objects.
// Array destructuring
const [a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
// Object destructuring
const { name, age } = { name: 'John', age: 30 };
console.log(name); // John
console.log(age); // 30
Spread Syntax
The spread syntax (…) is used to spread and expand an iterable, such as an array or a string, in places where zero or more arguments (for function calls) or elements (for array literals) are expected. It’s pretty handy for joining arrays or objects.
// Merging arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const mergedArr = [...arr1, ...arr2];
console.log(mergedArr); // [1, 2, 3, 4, 5, 6]
Closures
Closures are functions that, once defined, remember the variables of the place where they are defined and they have been executed, no matter where they are executed later. They provide essential programming patterns—function factories and modules.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const addFive = makeAdder(5);
console.log(addFive(2)); // 7
Function Composition
Function composition refers to the method of combining two or more functions with the objective of arriving at another function. It forms one of the basic ideas in functional programming that allow an elaboration of complex operations based on a set of single ones.
const add = (a, b) => a + b;
const square = x => x * x;
const addAndSquare = (a, b) => square(add(a, b));
console.log(addAndSquare(2, 3)); // 25
Event Delegation
Event delegation basically is the attaching of one event listener onto a parent element that centrally controls child element clicks. It works on the use of an event bubbling phase to handle events at a higher level, and therefore not only making events easier to manage but also conferring them with performance benefits.
document.getElementById('parent').addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
console.log('List item clicked:', event.target.textContent);
}
});
Web Workers
Web workers provide a simple means for web content to run scripts in background threads. By doing so, they can perform heavy tasks without interfering with the user interface.
// Main script
const worker = new Worker('worker.js');
worker.postMessage('Hello');
worker.onmessage = function(event) {
console.log('Received:', event.data);
};
// worker.js
onmessage = function(event) {
postMessage('Worker says: ' + event.data);
};
Memoization for Performance Optimization
The return value is cached after each call with a given set of arguments, and if it is called again with the same arguments, the result is retrieved from the cache. This is especially useful for functions that are called often with the same arguments.
function memoize(fn) {
const cache = {};
return function(...args) {
const key = args.toString();
if (key in cache) return cache[key];
else {
let result = fn(...args);
cache[key] = result;
return result;
}
};
}
// Example usage
const factorial = memoize(n => n <= 1 ? 1 : n * factorial(n - 1));
console.log(factorial(5)); // Calculates and caches
console.log(factorial(5)); // Retrieves from cache
Advanced Array Methods
Do complex operations more efficiently, such as processing array elements in reverse order using reduceRight
, mapping each element into an array, and then flattening results with flatMap
, testing whether all elements in an array pass a test with every
.
// reduceRight
const nestedArrays = [[1, 2], [3, 4], [5, 6]];
const flatArrayReversed = nestedArrays.reduceRight((acc, arr) => acc.concat(arr), []);
console.log(flatArrayReversed);
// flatMap
const sentences = ["Hello world", "Goodbye world"];
const wordArray = sentences.flatMap(sentence => sentence.split(" "));
console.log(wordArray);
// every
const allPositive = [1, 2, 3, 4].every(num => num > 0);
console.log(allPositive); // true if all elements are positive
Shuffling an Array
Randomly shuffling array elements can be achieved using the sort()
method combined with Math.random()
. This trick is one of my favourite in all of JavaScript tricks.
const array = [1, 2, 3, 4, 5];
const shuffledArray = array.sort(() => 0.5 - Math.random());
console.log(shuffledArray);
Optional Chaining and Nullish Coalescing
Safely access nested properties without worrying about them being null
or undefined
, and provide default values efficiently.
const obj = { a: { b: { c: 1 } } };
const value = obj?.a?.b?.c ?? 'default value';
console.log(value); // 1 if obj.a.b.c exists, else 'default value'
Using Function.prototype.bind()
:
This method allows creating a new function with a predetermined this
value and pre-set arguments, enhancing flexibility in code.
const module = {
x: 42,
getX: function() { return this.x; }
};
const unboundGetX = module.getX;
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // 42
Partial Function Application
By partially applying functions, you can fix a certain number of arguments and create a new function. This technique offers more flexibility in how functions are called and used
function add(a, b) {
return a + b;
}
const add5 = add.bind(null, 5);
console.log(add5(10)); // 15
Currying Functions
Transform a multi-argument function into a sequence of functions each with a single argument. This technique enhances function flexibility and composition.
const add = a => b => a + b;
const add3 = add(3);
console.log(add3(4)); // 7
const multiply = a => b => c => a * b * c;
const multiplyBy2 = multiply(2);
const multiplyBy2And3 = multiplyBy2(3);
console.log(multiplyBy2And3(4)); // 24
Wrapping Up
Mastering these JavaScript tricks can therefore optimize significantly your development process, making your code efficient, readable, and maintainable. Whether it’s simplifying access to data with destructuring
assignments or efficiently handling events
through delegation, let alone the way of improving the performance of the website using web workers
—these are all the necessary techniques.
The post JavaScript Tricks for Efficient Coding: Mastering Techniques Every Developer Should Know appeared first on TechTales.