JavaScript tips & tricks

Description πŸ˜‹

This is a collection of JavaScript tips and tricks. you can refer to it and apply it to make your code more concise. But don't overdo it, it can make your code difficult to read and maintain. Hope everyone contributes, thanks.

Table Of Content πŸ“ƒ

Array

1. Generate an Array
  • Create an empty array of length n

    var arr = new Array(3);
    
    // result: arr = [undefined, undefined, undefined]
  • Create an empty array of length n & fill value x

    var arr = [...Array(3).fill(1)];
    var arr2 = [...Array(5).fill(1, 0, 3)];
    
    /* 
      result: arr = [1, 1, 1]
              arr2 = [1, 1, 1, undefined, undefined]
    */
  • Create an array containing 0...n

    var arr = [...Array.keys(5)];
    
    // result: arr = [0, 1, 2, 3, 4]
  • Create an array containing 1...n

    var arr = [];
    for (let i = 0; arr.push(++i) < 4; );
    
    var arr2 = Array.from({ length: 4 }, (_, i) => i + 1);
    var arr3 = Array.from({ length: 4 }, (_, i) => i * 2);
    var arr4 = Array.from({ length: 4 }, () => Math.random());
    
    /* 
      result: arr =  [1, 2, 3, 4]
              arr2 = [1, 2, 3, 4]
              arr3 = [0, 2, 4, 6]
              arr4 = [0.211, 0.5123, 0.612, 0.8921]
    */
2. Extract Unique Values of Array
var arr = [1, 2, 2, 3, 5, 5, 4];
var newArr = [...new Set(arr)];

// result: newArr = [1, 2, 3, 5, 4]
3. Shuffle Elements from Array
var arr = [1, 2, 3, 4, 5];
var newArr = arr.sort(() => Math.random() - 0.5);

// result: newArr = [3, 1, 2, 4, 5]
4. Flatten a Multidimensional Array
var arr = [1, [2, 3], [4, 5, 6], 7];
var newArr = [].concat(...arr);

// result: [1, 2, 3, 4, 5, 6, 7]
5. Resize an Array

The length array isn't a read only property.

var arr = [1, 2, 3, 4, 5];
arr.length = 2;

var arr2 = [1, 2, 3, 4, 5];
arr2.length = 0;

var arr3 = [1, 2, 3, 4, 5];
arr3.length = 7;

/*
  result: arr = [1, 2]
          arr2 = []
          arr3 = [1, 2, 3, 4, 5, undefined, undefined]
*/
6. Random an Item in Array
var arr = [2, 4, 5];
var item = arr[Math.floor(Math.random() * arr.length)];
7. Remove an Item from Array
var arr = [1, 2, 3];

// Not Recommended
delete arr[1]; // arr = [1, undefined, 3], length = 3

// Recommended
arr.splice(1, 1); // arr = [1, 3], length = 2

Object

1. Dynamic Property Name
const dynamic = 'age',
	dynamicValue = 18;

var obj = {
	name: 'Dyno',
	[dynamic]: dynamicValue,
};

// result: obj = { name: 'Dyno', age: 18 }

2. Clone an Object
  • Shallow copy (Not Recommended)

    Use the = operator to copy object 1 into object 2. These 2 objects point to the same memory area (reference). Therefore, if we change object 1, object 2 will also change.

    var obj1 = { a: 1, b: 2 };
    var obj2 = obj1; // obj2 = { a: 1, b: 2 }
    
    obj1.a = 3; // change value of a property
    
    console.log(obj1); // { a: 3, b: 2 }
    console.log(obj2); // { a: 3, b: 2 } => property a of obj2 changed πŸ™‚β—
    console.log(obj3); // { a: 3, b: 2 } => property a of obj2 changed πŸ™‚β—
  • Deep copy

    Way 1: Use Spread operator {...} or Object.assign() to fix "Shallow copy". Issue: Nested objects still have shallow copy problem.

    var obj1 = { a: 1, b: 2, c: { nested: 3 } };
    var obj2 = { ...obj1 }; // obj2 = { a: 1, b: 2, c: { nested: 3 } }
    var obj3 = Object.assign({}, obj1); // obj3 = { a: 1, b: 2, c: { nested: 3 } }
    
    obj1.b = 3;
    obj1.c.nested = 4;
    
    console.log(obj1); // { a: 1, b: 3, c: { nested: 4 } }
    console.log(obj2); // { a: 1, b: 2, c: { nested: 4 } } πŸ™‚
    console.log(obj3); // { a: 1, b: 2, c: { nested: 4 } } πŸ™‚

    Way 2 (Recommended): Use JSON.stringify() & JSON.parse() to solve the above problems.

    var obj1 = { a: 1, b: 2, c: { nested: 3 } };
    var obj2 = JSON.parse(JSON.stringify(obj1)); // obj2 = { a: 1, b: 2, c: { nested: 3 } }
    
    obj1.b = 3;
    obj1.c.nested = 4;
    
    console.log(obj1); // { a: 1, b: 3, c: { nested: 4 } }
    console.log(obj2); // { a: 1, b: 2, c: { nested: 3 } } πŸ˜‰πŸ˜˜

Destructuring (ES6+)

1. With Array
var [a, b] = [1, 2];
// same: var a = 1, b = 2;

var [a, b, c] = [1, 2, 3, 4, 5];
// same: var a = 1, b = 2, c = 3;

var [a, , c] = [1, 2, 3, 4, 5];
// same: var a = 1, c = 3
// ignore values

var [a, b, ...rest] = [1, 2, 3, 4, 5];
// same: var a = 1, b = 2, rest = [4, 5]
// use "rest params ES6"

var [a, b, c] = [1, 2];
// same: var a = 1, b = 2, c = undefined;

var [a, b = 0, c = 0] = [1, 2];
// same: var a = 1, b = 2, c = 0;
// declare and set default value

var [a, b, [c, d], e] = [1, 2, [3, 4], 5];
// same: var a = 1, b = 2, c = 3, d = 4, e = 5
// nested array destructuring
2. With Object
var person = { name: 'Dyno', age: 18 };

var { name, age } = person;
// same: var name = person.name, age = person.age;

var { name = 'Anonymous', age = 1, address = 'HCM city' } = person;
// same: var name = person.name, age = person.age, address: 'HCM city'
// declare and set default value

var { name: personName, age: personAge } = person;
// same: var personName =  person.name, personAge = person.age
// decleare and change variable name

console.log({ name, age });
// same: console.log({ name: name, age: age })

var person = { name: 'Dyno', age: 18, infor: { address: 'HCM', phone: '123' } };
var {
	name,
	age,
	infor: { address, phone },
} = person;
// same: name = person.name, age = person.agem, address = person.infor.address, phone = person.infor.phone
// nested object destructuring

Operator

1. Optional chaining (?.)

"The optional chaining operator ?. enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid." MDN


const person = {
	name: 'Dyno',
	age: 18,
	sayHello: function () {
		console.log('Hello');
	},
};

// ❗ Wrong way
console.log(person.infor.address); // ❌ Uncaught TypeError: Cannot read property 'address' of undefined

// βœ… Right way (check condition)
if (person.infor) console.log(person.infor.address); // Not log

// βœ… Right way (use ?.)
console.log(person.infor?.address); // undefined

// Optional chaining with function calls
console.log(person.sayHello?.()); // Hello
console.log(person.callPhone?.()); // undefined

// A chain Optional chaining
console.log(person.infor?.address?.province?.name); // undefined
// syntax
obj.val?.prop;
obj.val?.[expr];
obj.arr?.[index];
obj.func?.(args);
2. Nullish coalescing operator (??)

"The nullish coalescing operator ?? is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand." MDN

var a = null ?? 'Default'; // a = 'Default'
var a = false ?? 'Default'; // a = false
3. Logical OR (||)
var a = 1,
	b = 2;

if (a > 2 || b > 1) console.log('Dyno');

// result: Dyno

The OR operator || is a logical operator that returns its right-hand side operand when its left-hand side operand is falsy, and otherwise returns its left-hand side operand.


var a = null || 'Default'; // a = 'Default'
var a = false || 'Default'; // a = 'Default'
4. Logical AND (&&)
let a = true,
	b = true,
	c = false;

if (a && b) console.log('Hello'); // Hello (a, b = true)

if (a && c) console.log('Dyno'); // not log (c = false)

// other usage
function sayHi() {
	console.log('Hi');
}

a && sayHi(); // Hi
c && sayHi(); // false
5. Double tilde operator (~~)
let num = 2.6;
console.log(~~num); // 2 = Math.floor(2)
6. Logical Assignment Operator ES12 (||=, ??=)
a ||= b; // same a = a || b;
a ??= b; // same a = a ?? b;
7. Numeric separator ES12 (_)
const n = 1_000_000_000; // same: n = 1000000000;

Comparison

1. Use === instead of ==

The operator == (!=) will automatically cast if 2 variables are not of the same type, then compare. The === (!==) operator compares the value and the type => === faster than ==.


  1 == '1' // true
  1 === '1' // false

  0 == false // true
  0 === false // false

  '' == false // true
  '' === false // false

  [] == 0 // true
  [] === 0 // false
2. The difference between isNaN() and Number.isNaN()

The isNaN() method (is Not a Number ?) use to check if a variable is a Number. The Number.isNaN() (is NaN ?) method use to check if a variable is NaN


isNaN('string');
// true, 'string' is not Number

isNaN([]);
// true, [] is not Number

isNaN(0 / 0);
// true, 0/0 is not Number

isNaN(1);
// false, 1 is Number

Number.isNaN('string');
// false, 'string' is not NaN

Number.isNaN([]);
// false, [] is not NaN

Number.isNaN(0 / 0);
// true, 0/0 is NaN

Number.isNaN(NaN);
// true

Others

1. Swapping use Destructuring
let a = 1,
	b = 2;

[a, b] = [b, a];

// result: a = 2, b = 1;
2. Create function that returns only 1 object
const fn = () => ({ obj: 1 });

/*
  same: const fn = () => {
    return { obj: 1 }
  }
*/
3. Immediately Invoked Function Expression (IIFE)

The function will execute automatically when you create it.


  // Way 1:
  var res = ()(function(){
    // do something...
    console.log("Hello");
    return true;
  })();
  // result: Hello, res = true;

  // Way 2:
  var res = (() => {
    console.log('Hello');
    return true;
  })();
  // result: Hello, res = true;
4. typeof vs instanceof

typeof: return a string that represents the primitive type of a variable.

instanceof: check in all the prototypes chain the constructor it returns true if it’s found and false if not.


var arr = [1, 2, 3];
console.log(typeof arr); // "object"
console.log(arr instanceof Array); // true

typeof 1; // "number"
typeof NaN; // "number"
typeof 'str'; // "string"
typeof true; // "boolean"
typeof {}; // "object"
typeof []; // "object"
typeof null; // "object"
typeof undefined; // "undefined"
typeof function name() {}; // "function"
5. Falsy

A Falsy value is a value that is considered false when encountered in a Boolean context . MDN

Complete list of JavaScript falsy values false, 0, -0, 0n, "", '', ``, NaN, null, undefined, document.all

Falsy value bypass the if block. Ex:


if (null) {
} else {
	console.log('Falsy');
}

const a = undefined || 'Falsy';

// result: Falsy, a = "Falsy"

Filter out Falsy values


const arr = [1, 'Dyno', false, 0, true, NaN, 2000];
var filteredArr = arr.filter(Boolean);

// result: filteredArr = [1, "Dyno", true, 2000]
6. Template string `${}`
const name = 'Dyno';
const hello1 = 'Hello ' + name + ', how are you?';
const hello2 = `Hello ${name}, how are you?`; // template string.
7. Rounding number to n decimal place
var num = 25.0420001;
console.log(typeof num); // "number"

num = num.toFixed(2); // num = "25.04"
console.log(typeof num); // ❗ "string"
8. Check variable - convert a variable to Boolean (!! operator)
console.log(!!null); // false
console.log(!!undefined); // false
console.log(!!1); // true