Some interesting tricks, tips, shorthand, and best practices of modern JavaScript

Brandon Lara
8 min readAug 24, 2021

JavaScript is a language that has been used for many years in almost every software stack,

Swap variables values without using auxiliary or temporal variables

Sometimes we need to swap the values of variables, and we usually do it using auxiliary variables, or the XOR swap algorithm.
However, in JavaScript this exchange can be done using destructuring assignment as you can see below:

let a = 1;
let b = 2;
[a,b] = [b,a];
console.log(a); // 2
coonsole.log(b); // 1

By doing it this way the code is more readable, shorter and looks cleaner, we even program it faster, and it is possible to save a few resources.

You can find more information about this syntax at the following link:

Use console.table to print data structures.

The console object provides access to the debugging console, from this object we usually use the console.log() method to display its arguments in the debugging console.

But the console object has other methods with different usages and functionalities for debugging, which are virtually unused, or we didn’t even know they existed. However, I believe that the console.table() method is one of the most interesting because it displays tabular data as a table.

This method can display in the debug console the values of simple data structures in a very clear and readable way, as you can see in the following example:

console.table({a:1, b:2});

When the argument is an array, the console displays something similar to the above with the difference that in the first column of the table (index) the array indexes are displayed instead of the properties, a very clear example of this is shown below:

console.table(['car', 'plane', 'bus', 'bike']);

The most interesting It's when we have a structured array of the same simple objects like the example below:

console.table(
[
{
id: 1,
name: 'foo',
date: new Date('2023'),
active: true,
}, {
id: 2,
name: 'bar',
date: new Date('2020'),
active: false
},
{
id: 3,
name: 'bran',
date: new Date('2022'),
active: true
}
]);

This way, the information is displayed in a very clear and understandable way, making it easy to debug collections of structured data. This method is quite practical for inspecting and analyzing the data returned by the APIs.

You can find more information about the console.table() method at the following link:

The generator functions

Generators are functions that can be exited and later re-entered multiple times, and their context (variable bindings) will be saved across re-entrances.

Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator’s next() method is called, the generator function's body is executed until the first yield expression.

The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value, as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield expression where an execution was paused with the argument from next()

A return statement in a generator, when executed, will make the generator finish (i.e. the done property of the object returned by it will be set to true).

As an example of this, I will show you below a simple id generator function with an id generation limit that would be passed as a parameter:

function* idGenerator(max) {
var index = 0;
while (index <= max)
yield index++;
return true;
}

var idGen = idGenerator();

function* idGenerator(max) {
var index = 0;
while (index <= max)
yield index++;
return;
}
var idGen = idGenerator(2);
console.log(idGen.next().value); // 0
console.log(idGen.next().value); // 1
console.log(idGen.next().value); // 2
console.log(idGen.next().value); // undefined
/* It's the same example as above, but without reading the value directly to show the done property, that is set to true once the generator executes the return statement*/idGen = idGenerator(2); /* Calling the generator again to reset it in the idGen variable. */console.log(idGen.next()); // { value: 0, done: false }
console.log(idGen.next()); // { value: 1, done: false }
console.log(idGen.next()); // { value: 2, done: false }
console.log(idGen.next()); // { value: undefined, done: true }

Generators in JavaScript — especially when combined with Promises — are a very powerful tool for asynchronous programming as they mitigate — if not entirely eliminate — the problems with callbacks, such as Callback Hell and Inversion of Control. However, an even simpler solution to these problems can be achieved with async functions.

These generators can have complex uses, such as yield return values, generator and yield parameters, or the yield* syntax to delegate to one generator inside another. As all this would be enough for a whole separate post, it is best to access the following links to find some good explanations, information and examples:

Rest parameters

In JavaScript, the last function parameter can be prefixed with “..." to place in it all the remaining parameters as an array.

The rest parameter syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic functions in JavaScript.

The next example shows a function that prints with the log method the first value and displays with the table method the rest parameter array:

const print = (first,...rest)=>{
console.log(first);
console.table(rest)
}
print(1,2,3,4,5,6);/*1| (index) | Values |
|---------|--------|
| 0 | 2 |
| 1 | 3 |
| 2 | 4 |
| 3 | 5 |
| 4 | 6 |
*/print(1,2);
/*
1| (index) | Values |
|---------|--------|
| 0 | 2 |
*/

This has a multitude of uses, but the most important is that it improves the code maintainability, keeps it clean, making it easy to read, and understand. In my experience, using this syntax helped me a lot with good results, especially when implementing recursive functions.

You can find more information and examples about the Rest parameters in the following link:

Find the max or the min values in an array

This is a simple and easy tip that consists in using the spread syntax to call the Math.hypot() ,Math.max() and Math.min() methods. In this way we can directly pass arrays as arguments to these methods to perform their operations on the array as in the following examples to find the maximum and minimum value of an array:

var array = [2, 8, 15, 4]
console.log(Math.max(...array)); // 15
console.log(Math.min(...array)); // 2

We can use the Math.hypot() square root of the sum of squares of arrays of vectors like in the example below:

const vector = [5, 3, 2, 1];
console.log(Math.hypot(...vector)); // 6.244997998398398

You can find more information about the spread syntax and Math metods in the following links:

Shorthand object property assignment

Since ECMAScript 2015 there are new initializer notations, like the Shorthand property names and Shorthand method names that are not sufficiently well known even though their use makes the code look much cleaner, readable and understandable.

These notations consist of creating objects from variables, without having to explicitly specify the property names since the property name of each value is that of its variable, this can be clearly seen in the following code snippet:

var name = 'bran';console.log({bran}); // { name: 'bran' }

For example, we can use it to create an object from different variables or parameters as shown below:

const displayAsObject = (name, color, active) => {
console.log({name,color,active})
}
displayAsObject('bran','red',true); /* { name: 'bran', color: 'red', active: true } */

It is a fairly simple and trivial example, but despite that, you can see the potential that these notations can have. In my case, it is something I use very often in forms, when creating the body of POST requests, debugging variables and especially when programming in React or React Native.

You can see more information and examples about this in the links below:

This is all for this post, I still know some other tricks that I will publish over time. But above all, I hope they will help you to write better code overall (Clean, legible, understandable and fast). Anyway, if you have any suggestions or doubt you can comment here without any problem, I will answer you as soon as possible 😃👍

Greetings!

References and information about this post:

--

--