12 JavaScript tricks not found in most tutorials

Original author: Bret Cameron
  • Transfer

When I started learning JavaScript, the first thing I did was make a list of tricks that helped me save time. I spied them on other programmers, on different sites and in manuals.

In this article, I will show you 12 great ways to improve and speed up your JavaScript code. In most cases, they are universal.

We remind you: for all readers of “Habr” - a discount of 10,000 rubles when registering for any Skillbox course using the “Habr” promo code.

Skillbox recommends: Practical course "Mobile Developer PRO" .

Unique Value Filtering


type of the Set object was introduced in ES6, together with the ..., spread-operator, we can use it to create a new array that contains only unique values.

const array = [1, 1, 2, 3, 5, 5, 1]
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // Result: [1, 2, 3, 5]

In a normal situation, much more code is needed to perform the same operation.

This trick works for arrays containing primitive types: undefined, null, boolean, string and number. If you are working with an array containing objects, functions, or additional arrays, you will need a different approach.

The length of the cache in cycles


When you learn for for loops, you follow the standard procedure:

for (let i = 0; i < array.length; i++){

However, with this syntax, the for loop re-checks the length of the array at each iteration.

This can sometimes be useful, but in most cases it is more efficient to cache the length of the array, which will require a single access to it. We can do this by defining a variable length, where to set the variable i, for example, like this:

for (let i = 0, length = array.length; i < length; i++){

In principle, it is almost the same as above, but with an increase in the size of the cycle, we will get significant time savings.

Short circuit rating (McCarthy rating)


ternary operator is a quick and efficient way to write simple (and sometimes not very simple) conditional statements:

x> 100? “Greater than 100”: “less than 100”;
x> 100? (x> 200? "more than 200": "between 100-200"): "less than 100";

But sometimes even a ternary operator is more complicated than required. Instead, we can use 'and' && and 'or' || logical operators to evaluate some expressions in an even more concise way. It is often called a “short circuit” or “short circuit assessment”.

How it works

Let's say we want to return only one of two or more conditions.

Using && will return the first false value. If each operand evaluates to true, the last evaluated expression will be returned.

let one = 1, two = 2, three = 3;
console.log(one && two && three); // Result: 3
console.log(0 && null); // Result: 0

Using || will return the first true value. If each operand evaluates to false, then the last calculated value will be returned.

let one = 1, two = 2, three = 3;
console.log(one || two || three); // Result: 1
console.log(0 || null); // Result: null

Example 1

Let's say we want to return length to a variable, but we don’t know its type.

In this case, you can use if / else to verify that foo is a suitable type, but this method may be too long. Therefore, it is better to take our "short circuit".

return (foo || []).length;

If the variable foo has a suitable length, then it will be returned. Otherwise, we get 0.

Example 2

Have you had any problems accessing the attached object? You may not know if an object or one of its subproperties exists, and this can lead to problems.

For example, we wanted to access the data property in this.state, but data is not defined until our program returns a query for the selection.

Depending on where we use it, a call to this.state.data may prevent the application from starting. To solve the problem, we could wrap this in a conditional expression:

if (this.state.data) {
  return this.state.data;
} else {
  return 'Fetching Data';

A more suitable option would be to use the "or" operator.

return (this.state.data || 'Fetching Data');

We cannot change the code above to use &&. The 'Fetching Data' && this.state.data statement will return this.state.data whether it is undefined or not.

An optional chain

You can suggest using an optional chain when trying to return a property deep into a tree structure. So, a question mark symbol? can be used to retrieve a property only if it is not null.

For example, we could refactor the example above by getting this.state.data? .. (). That is, data is returned only if the value is not null.

Or, if it is important whether state is defined or not, we could return this.state? .Data.

Convert to Boolean


Besides the usual logical functions true and false, JavaScript also treats all other values ​​as truthy or falsy.

Unless otherwise specified, all values ​​in JavaScript are truthy, with the exception of 0, "", null, undefined, NaN, and, of course, false. The latter are falsy.

We can easily switch between the two using the! Operator, which also converts the type to logical.

const isTrue  = !0;
const isFalse = !1;
const alsoFalse = !!0;
console.log(isTrue); // Result: true
console.log(typeof true); // Result: "boolean"

Convert to string


Quickly convert an integer to a string as follows.

const val = 1 + "";
console.log(val); // Result: "1"
console.log(typeof val); // Result: "string"

Conversion to integer


perform the inverse transformation as follows.

let int = "15";
int = +int;
console.log(int); // Result: 15
console.log(typeof int); Result: "number"

This method can also be used to convert the boolean boolean data type to regular numeric values, as shown below:

console.log(+true);  // Return: 1
console.log(+false); // Return: 0

There may be situations where + will be interpreted as a concatenation operator rather than addition. To avoid this, use tildes: ~~. This operator is equivalent to the expression -n-1. For example, ~ 15 is -16.

Using two tildes in a row negates the operation, because - (- - n - 1) - 1 = n + 1 - 1 = n. In other words, ~ -16 is 15.

const int = ~~"15"
console.log(int); // Result: 15
console.log(typeof int); Result: "number"


Starting with ES7, you can use the exponentiation operator ** as an abbreviation for degrees. This is much faster than using Math.pow (2, 3). It seems simple, but this moment is included in the list of receptions, since it is not mentioned everywhere.

console.log(2 ** 3); // Result: 8

Do not confuse it with the symbol ^, which is usually used for exponentiation. But in JavaScript, this is the XOR operator.

Prior to ES7, the abbreviation ** could only be applied for degrees with base 2 using the bitwise left shift operator <<:

Math.pow(2, n);
2 << (n - 1);

For example, 2 << 3 = 16 is equivalent to the expression 2 ** 4 = 16.

Float integer


If you need to convert a float to an integer, you can use Math.floor (), Math.ceil (), or Math.round (). But there is a faster way, for this we use |, that is, the OR operator.

console.log(23.9 | 0);  // Result: 23
console.log(-23.9 | 0); // Result: -23

Behavior | to a large extent depends on whether you are dealing with positive or negative numbers, so this method is only suitable if you are confident in what you are doing.

n | 0 removes everything after the decimal separator, truncating the floating-point number to an integer.

You can get the same rounding effect using ~~. After forced conversion to an integer, the value remains unchanged.

We remove trailing numbers.

The OR operator can be used to remove any number of digits from a number. This means that we do not need to convert types, as here:

let str = "1553";
Number(str.substring(0, str.length - 1));

Instead, we simply write:
console.log(1553 / 10   | 0)  // Result: 155
console.log(1553 / 100  | 0)  // Result: 15
console.log(1553 / 1000 | 0)  // Result: 1

Auto Link


ES6 dials can be used in class methods, and binding is implied. Thanks to this, you can say goodbye to duplicate expressions such as this.myMethod = this.myMethod.bind (this)!

import React, { Component } from React;
export default class App extends Compononent {
  constructor(props) {
  this.state = {};
myMethod = () => {
    // This method is bound implicitly!
render() {
    return (
) } };

Array trimming


If you need to remove values ​​from an array, then there are faster methods than splice ().

For example, if you know the size of the original array, you can override its length property as follows:

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
array.length = 4;
console.log(array); // Result: [0, 1, 2, 3]

But there is another method, and faster. If speed matters to you, then here is our choice:

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
array = array.slice(0, 4);
console.log(array); // Result: [0, 1, 2, 3]

Output last array value (s)

This technique requires the use of the slice () method.

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(array.slice(-1)); // Result: [9]
console.log(array.slice(-2)); // Result: [8, 9]
console.log(array.slice(-3)); // Result: [7, 8, 9]

JSON code formatting


may have already used JSON.stringify. Do you know that it helps format your JSON?

The stringify () method accepts two optional parameters: the replacer function, which can be used to filter the displayed JSON, and the value space.

console.log(JSON.stringify({ alpha: 'A', beta: 'B' }, null, '\t'));
// Result:
// '{
//     "alpha": A,
//     "beta": B
// }'

That's all, I hope that all these tricks were useful. And what tricks do you know? Write them in the comments.

Skillbox recommends:

Also popular now: