JS operators are used every day, as well as some new utility operators in ES2020 and ES2021, which together make up the flexible syntax ecosystem of JS. In this article, we will introduce some common but powerful operators in JS. Let’s take a look

1. Numeric separator _

ES2021 introduces the numeric separator _, which provides separation between groups of values, making a long numeric value easier to read. Chrome already provides support for numerical separators, which you can try out in your browser.

let number = 100 _0000_0000_0000 // The number of zeros is too large to use
console.log(number)             / / output 100000000000000
Copy the code

In addition, numeric separators can be used for the decimal part of the decimal system, as well as for binary and hexadecimal systems.

0x11_1= = =0x111   // true hexadecimal
0.11 _1= = =0.111   // true is a decimal number
0b11_1= = =0b111   // true binary
Copy the code

2. Comma operator,

What, can a comma be an operator? Yes, you’ve seen a simple function that reverses the first and second items in an array and returns the sum of the two items:

function reverse(arr) {
    return [arr[0], arr[1]]=[arr[1], arr[0]], arr[0] + arr[1]}const list = [1.2]
reverse(list)   // Return 3, then list is [2, 1]
Copy the code

The comma operator evaluates each of its operands (left to right) and returns the value of the last operand.

expr1, expr2, expr3...
Copy the code

Returns the result of the last expression, expr3, and all other expressions are evaluated.

3. Zero merge operator??

The zero merge operator?? Is a logical operator that returns the right-hand operand if the left-hand operand is null or undefined, otherwise returns the left-hand operand.

expr1 ?? expr2
Copy the code

Null values merge operators are commonly used to provide default values for the constants, ensure constant is not null or undefined, normally use | | to do the work variable = variable | | ‘bar’. However, due to the | | is a Boolean logical operators, the left operand are forced into Boolean value for evaluation. Any false values (0, “, NaN, null, undefined) will not be returned. This leads to unexpected consequences if you use 0, “, NaN as valid values.

Because | | existence the question, and???? Is to solve these problems,?? Undefined and null are returned only if the left side is null. Can be understood as | | the perfect solution.

To get a feel, execute the following code in a browser:

undefined || 'default' // 'default'
null || 'default'      // 'default'
false || 'default'     // 'default'
0 || 'default'         // 'default'

undefined ?? 'default' // 'default'
null ?? 'default'      // 'default'
false ?? 'default'     // 'false'
0 ?? 'default'         / / 0
Copy the code

In addition, when assigning, we can use the abbreviation of the assignment operator?? =

let a = {b: null.c: 10} a.b ?? =20a.c ?? =20
console.log(a)     {b: 20, c: 10}
Copy the code

4. Optional chain operators? .

Optional chain operator? . Allows you to read the value of a property deep in the chain of connected objects without having to verify that each reference in the chain is valid. ? The. Operator functions like the. Chain operator, except that it does not raise an error when a reference is null or undefined, and the expression shorts back undefined.

The optional chain operator makes the expression shorter and more concise when trying to access an object property that may not exist.

const obj = {
  a: 'foo'.b: {
    c: 'bar'}}console.log(obj.b? .c)/ / output bar
console.log(obj.d? .c)/ / output is undefined
console.log(obj.func? . ()// output undefined without error
Copy the code

Where previously it was possible to get a deeply nested child property through obj && obj.a && obj.a.b, it is now possible to get a deeply nested child property directly through obj? .a? B.

In addition to retrieving an object’s property, optional chains can also be used to retrieve an array’s index, arr? .[index], can also be used to determine functions func? .(args), which can also be used when trying to call a method that may not exist.

When calling a method on an object that may not exist (for version reasons or if the current user’s device does not support the function), using an optional chain allows the expression to return undefined if the function does not exist instead of throwing an exception.

constresult = someInterface.customFunc? . ()Copy the code

5. Private methods/attributes

Properties in a class can be marked private by adding a # private tag to the front of them. In addition to properties being marked private, getters/setters can also be marked private, and methods can also be marked private.

class Person {
  getDesc(){ 
    return this.#name +' '+ this.#getAge()
  }
  
  #getAge(){ return this.#age } // Private methods

  get #name(){ return 'foo' } // Private accessors
  #age = 23                   // Private attributes
}
const a = new Person()
console.log(a.age)       // undefined cannot be accessed directly
console.log(a.getDesc()) // foo 23
Copy the code

6. Bitwise operators >> and >>>

The signed right-shift operator >> moves the first operand to the right by a specified number of digits. Excess shifts to the right are discarded. Because the new left-most bit has the same value as the previous left-most bit, the sign bit (left-most bit) does not change.

(0b111>>1).toString(2)   / / "11"
(-0b111>>1).toString(2)  // "-100" doesn't feel intuitive
Copy the code

Positive number is easy to understand, how to understand negative numbers, negative numbers in the computer is stored in accordance with the complement code to store, the calculation method of the complement code is to take the inverse plus one, when the shift will complement the form of the right, the leftmost complement symbol bit, after the move, again take the inverse plus one to obtain the complement code after processing.

-111      / / true value
1 0000111 // Set the value of 0 to 0.
1 1111001 / / complement
1 1111100 // Count the right shift
1 0000100 // get the original code
-100      // The shifted truth value
Copy the code

We use >> to divide a number by 2, which is equivalent to discarding the decimal place and then doing a Math. Floor:

10 >> 1    / / 5
13 >> 1    // 6 is equivalent to
13.9 >> 1  / / 6
-13 >> 1   // -7 equals
-13.9 >> 1 / / - 7
Copy the code

The unsigned right shift operator >>> moves the sign bit to the right as part of the binary data, and the high position is always filled with 0. There is no difference between a positive integer and an arithmetic right shift. For a negative number, the result is always non-negative because the sign bit is filled with 0 and becomes a positive number. Even if you move 0 bits to the right, it’s nonnegative.

(0b111>>>1).toString(2)   / / "11"
(-0b111>>>1).toString(2)  / / "1111111111111111111111111111100"
Copy the code

One way to think about it is this

-111      / / true value
1 000000000000000000000000000111 / / the original code
1 111111111111111111111111111001 / / complement
0 111111111111111111111111111100 // Count to the right (since the right is a positive number, do not calculate the complement)
1073741820      // The shifted truth value
Copy the code

Similarly, the left-shift operator << is simple: the left removes the highest bit and the lowest fills 0:

(0b1111111111111111111111111111100<<1).toString(2)   / / "- 1000"
(0b1111111111111111111111111111100<<<1).toString(2) // "-1000"Copy the code

There is no unsigned left shift in PS: JS, and there is no unsigned left shift in other languages such as JAVA.

7. An operator & and |

An operator is a bitwise operations, & with, | or, ~, ^ the bitwise xor:

& :1010| :1010To:1010^ :1010
   0110     0110              0110
   ----     ----     ----     ----
   0010     1110     0101     1100
Copy the code

Using an operator will abandon decimal places, we can use this feature to digital integer, such as to any digital & binary 32 1, or | 0, the latter apparently simple some.

So we can pick it up on a digital | 0 ‘clock, negative as well

1.3 | 0         / / 1
-1.9 | 0        // -1
Copy the code

In addition to the common mod % 2, you can also use &1 to determine whether the lowest digit of the binary number is 1, so that except for the lowest digit are set to 0, the result of mod only the lowest digit, is not very clever. Negative numbers also work:

const num = 3!!!!! (num &1)                    // true!!!!! (num %2)                    // true
Copy the code

8. The two-bit operator ~~

You can use the two-bit operator to replace math.floor () for positive numbers and math.ceil () for negative numbers. The advantage of the double-negated operator is that it performs the same operation faster.

Math.floor(4.9) = = =4      // true
//~ ~4.9= = =4      // true
Copy the code

Note, however, that ~~ is the same as math.floor () for positive numbers and math.ceil () for negative numbers:

~ ~4.5                / / 4
Math.floor(4.5)      / / 4
Math.ceil(4.5)       / / 5~ ~ -4.5               / / - 4
Math.floor(-4.5)     / / - 5
Math.ceil(-4.5)      / / - 4
Copy the code

Note the difference between ~~(num/2) and num >> 1 when the value is negative

9. Short circuiting operators && and | |

We know that logic and && and | or logical | is short-circuit operator, short-circuit operator is from left to right in the operation which meet the requirements, will no longer perform the latter.

It can be understood as:

  • &&For false operation, judging from left to right, if a false value is encountered, the false value is returned, and no further execution, otherwise the last true value is returned
  • ||For true operation, judging from left to right, if a true value is encountered, the true value is returned, no further execution, otherwise the last false value is returned
let param1 = expr1 && expr2
let param2 = expr1 || expr2
Copy the code
The operator The sample instructions
&& expr1&&expr2 Return expr1 if expr1 can be converted to false, expr2 otherwise. Therefore, when used in Boolean environments, it returns true if both operations result in true, and false otherwise
|| expr1||expr2 Return expr1 if expr1 can be converted to true, expr2 otherwise. Therefore, when used in Boolean environments (in if conditionals), return true as long as either operation is true; Return false if both operations result in false
! ! expr Return false if a single expression can be converted to true, true otherwise

It can therefore be used to do many interesting things, such as assigning initial values to variables:

let variable1
let variable2 = variable1  || 'foo'
Copy the code

If variable1 is true, it returns directly, and subsequent short-circuits are not returned; if false, foo is returned.

Can also be used for simple judgments instead of lengthy if statements:

let variable = param && param.prop
// With the optional chain can be directly param? .prop
Copy the code

Return param.prop if param is true, false otherwise. This prevents an error in some places when param is undefined.

Void operator

The void operator evaluates the given expression and returns undefined

The void operator allows the JS engine to recognize a function keyword as a function expression rather than a function declaration when using IIFE immediately.

function iife() { console.log('foo') }()       // Error because the JS engine recognizes IIFE as a function declaration
void function iife() { console.log('foo') }()  // Normal call
~function iife() { console.log('foo') }()      // A bitwise operator can also be used
(function iife() { console.log('foo') })()     // Or simply use parentheses to represent the whole expression
Copy the code

It can also be used in arrow functions to avoid leakage, which allow the function body to return a value without using parentheses. This feature brings a lot of convenience to the user, but sometimes it also causes unnecessary trouble. If a function is called on the right side of the function that does not return a value, its return value can change, resulting in unexpected side effects.

const func = () = > void customMethod()   // Especially when passing a function to an event or callback function
Copy the code

To be safe, use void to ensure that undefined is returned when you do not want the function to return anything other than a null value, so that changes to the customMethod return value do not affect the behavior of the arrow function.

11. Other common operators

  1. Ternary expression: It’s easy. People use it a lot.expr ? expr1 : expr2ifexprReturns if trueexpr1Otherwise returnexpr2
  2. Short for the assignment operator: Addition assignment+ =, subtraction assignment- =And multiplication assignment* =, division assignment/ =, exponentiation and assignment* * =, bitwise or copy| =, bitwise and assignment& =, signed bitwise right shift assignment> > =, unsigned bitwise right shift assignment> > > =, logical empty assignment?? =.
  3. Exponentiation operator:var1 ** var2The equivalent ofMath.pow, the results forvar1var2To the power

12. Operator priority

Because of the precedence of the operator, variable = 1, 2 means assigning a variable to 1 and then returning a number 2, rather than assigning a variable to 1 and 2 and returning a number 2, because the = operator has higher precedence than the comma operator. Another example is the expression 6-2 * 3 === 0 && 1, – * === = && the highest priority of the four operators is * first, then the – operator is 0, === is higher than && and true && 1 is 1, so this is the result of the operation.

The following table lists the operators in order of priority from high (20) to low (1), but it is not up to date, at least not with optional chains, and it is recommended to refer to this table or MDN.


Online posts are mostly different in depth, and even some inconsistent, the following article is a summary of the learning process, if you find mistakes, welcome to point out that if this article helps you, don’t forget to support oh, your praise is the biggest power OF my update! (Collection is not praise, are playing rogue 🤣) ~

Reference Documents:

  1. Operator precedence – JavaScript | MDN
  2. JS tips for increasing happiness
  3. 4 powerful JavaScript operators you’ve never heard of
  4. Talk about binary numbers in JavaScript

PS: This article is included in the following blog Github – SHERlocked93/blog series of articles, welcome to pay attention to my public number front-end afternoon tea, direct search can be added or click here to add, continue to push for you front-end and front-end surrounding related quality technical articles, common progress, together with oil ~