Now JavaScript has added some operators that are easier and more efficient to manipulate without some additional processing.

Nowadays, JavaScript releases a new version every year, and it adds some new operators that are more convenient and efficient to use. Today we’ll take a look at some of these efficient magic operators.

1. Optional Chain Operators

Previously, when we wanted to use a property with a deeper structure, and we couldn’t be sure that all the parents must exist, we needed to make a series of judgments, such as a data structure.

1
2
3
4
5
const student = {
  score: {
    math: 98,
  },
};

When we want to get the value of the innermost math property.

1
2
3
if (student && student.score) {
  console.log(student.score.math);
}

1.1 Getting deep properties

But when we use the optional chain operator, the judgment is much easier. The optional chain operator will return undefined directly when it encounters null or undefined on the link, without throwing an error exception.

1
console.log(student?.score?.math);

1.2 Executing an optional method

It can also be used when executing a function that may exist. For example a react component where the method passed in is optional.

1
2
3
4
5
6
7
8
9
// getScore 是一个可选参数,要么是 undefined,要么是一个函数
const Student = ({ getScore }: { getScore?: () => void }) => {
  useEffect(() => {
    // 当 getScore 存在时,正常执行 getScore()方法
    getScore?.();
  }, []);

  return <div></div>;
};

Or we can use it when we execute a method on a dom element.

document.querySelector returns two types, when the dom element is real and null otherwise, and anyone who has written typescript knows that when we want to call a method, we always need to make sure the dom element exists first.

1
2
3
4
const dom = document.querySelector('.score');
if (dom) {
  dom.getBoundingClientRect(); // 当 dom 元素存在时,才执行该方法
}

When using the optional chain operator, it is sufficient to call directly.

1
document.querySelector('.score')?.getBoundingClientRect();

1.3 Getting the value in an array

If the array exists, get the value of some subscript. We don’t need to determine whether the array exists now, we can just use it.

1
arr?.[1]; // 若 arr 存在时,则正常获取 arr[1]中的值

The above 3 cases can also be used in combination. If a structure is complex and has various types, here we have to execute the method of subscript 2 of the array math.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const student = {
  score: {
    math: [
      98,
      67,
      () => {
        return 99;
      },
    ],
  },
};

Execution.

1
student?.score?.math?.[2]?.(); // 99

1.4 Assignment is not possible

The optional chain operator can only perform get operations, not assignments.

For example, if you assign a value to a possible array or dom element, a syntax exception will be thrown directly.

1
2
arr?.[1] = 2; // x
document.querySelector('.score')?.innerHTML = 98; // x

When we execute the above statement, the following prompt will be thrown.

1
Uncaught SyntaxError: Invalid left-hand side in assignment

That is, you cannot assign a value to the optional chain on the left side.

2. The double question mark operator

The double question mark operator ?, as I understand it, is designed to solve the or operator ||.

Let’s review the operation of the or operator. When the data on the left side is a false value (number 0, boolean false, empty string, undefined, null), then the statement on the right side is executed.

1
2
3
4
5
false || 123;
0 || 123;
'' || '123';
undefined || 123;
null || 123;

However, there are cases where both false and 0 are normal values, but when using the or operator, this can lead to errors.

For example, in the example below, when score is empty, the default value is 1. When the normal value of 0 is entered, it should return 0 (but it actually returns 1).

1
2
3
4
5
const getSCore = (score: number) => {
  return score || 1;
};

getScore(0); // 1

This is where we use the double question mark operator ? . The double question mark operator will only execute the right-hand side of the statement if the left-hand side is undefined or null.

1
2
3
4
5
const getSCore = (score: number) => {
  return score ?? 1;
};

getScore(0); // 0

Also, the double question mark operator can be combined with = as an assignment operation that assigns the result of the right-hand statement to the left-hand variable when the left-hand side is null or undefined.

1
score ??= 1; // 1

3. The & and | assignment operations

We wrote it like this when we used the or operator for assignment operations before.

1
2
score = score || 1;
age = age && 24;

Now you can just shorten it to this.

1
2
score ||= 1; // 等同于 score = score || 1
age &&= 24; // 等同于 age = age && 24

4. The double asterisk operator

The double asterisk operator ** was introduced to js earlier, but we don’t use it as much. It actually performs a power operation, which is equivalent to Math.pow().

1
2 ** 10; // 1024, 2的10次方,等同于 Math.pow(2, 10);

5. Summary

All the above samples have been run on chrome90.