1. JS operator

In addition to the standard arithmetic operators (+, -, * /), JavaScript provides the arithmetic operators in the following table.

Operator Description Example
For more than (%) Binary operator. returns the remainder of division. 12%5 returns 2.
Since the increasing (++) Unary operator. Increments the value of the operand by one. If placed before the operand (++x), returns the value after adding one; If placed after the operand (x++), returns the operand and then increments it by one. var x=3; ``console.log(++x); //4``console.log(x); //4``var y=3; ``console.log(y++); //3``console.log(y); / / 4
The decrement (--) Unary operator. Reduces the value of the operand by one. The return value of both prefixes and suffixes is similar to that of the increment operator. var x=3; console.log(–x); // enter 2,x=2var y=3; console.log(y–); / / output 3, x = 2;
Unary negative character (-) Unary operator that returns a negative value of its operand. var x=3; console.log(-x); / / input – 3
Unary positive character (+) The unary operator attempts to convert the operand to number if it was not number before console.log( +'3' ); // 3``console.log( '3' ); / / '3'console.log(+true); / / 1
Index operator (**) To calculateThe base (base)exponent(index) to the powerDenoted bybaseexponent 2 * * 3 returns 8. 10 ** -1 returns 0.1.

An operator

The bitwise operator treats its operands as 32-bit binary strings (0s and 1s) rather than decimal octal or hexadecimal numbers. For example, the decimal number 9 is expressed in binary as 1001, and the bit operator performs operations on this binary representation, but returns a standard JavaScript number.

The following table summarizes JavaScript bitwise operators.

Operator Usage Description
Bitwise AND [AND] a & b In the bit representation of a and b, return 1 if each corresponding bit is 1, otherwise return 0.
4. by position OR [OR] `a b`
Bitwise XOR [XOR] a ^ b In the bit representation of a and b, 1 is returned if the two bits are different, and 0 is returned if the two bits are the same.
Bitwise NOT [NOT] ~ a Inverts the bit of the operand.
Left [shift] a << b Move the binary string of A to the left by b bits and to the right by 0.
Arithmetic moves to the right a >> b Move the binary representation of A to the right by b bits, discarding any bits removed.
Unsigned right shift (left empty space is filled with 0) a >>> b Move the binary representation of A b bits to the right, discarding all the bits removed, and padding all the bits left vacant with zeros

Bitwise logical operators

Conceptually, bitwise logical operators work as follows:

  • Operands are converted to 32bit integers represented as a sequence of bits (0 and 1). If the value exceeds 32bits, the value is the lowest 32bits, as shown in the following figure:

  • Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001

  • Each bit of the first operand is paired with the corresponding bit of the second operand: the first to the first, the second to the second, and so on.

  • Operators are applied to each pair of bits, and the final result is combined by the results of each pair of bits.

For example, the binary representation of the decimal number 9 is 1001, and the binary representation of the decimal number 15 is 1111. Therefore, when the bitwise operator is applied to these two values, the result is as follows:

expression The results of Binary description
15 & 9 9 1111&1001 = 1001
` 15 9 ` 15
15 ^ 9 6 1111 ^ 1001 = 0110
~ 15 - 16 ~ ` ` 00000000... 1111 ` ` ` 00001111 = ` ` ` 1111 ` `... ` ` 11110000
~ 9 - 10 00000000 ~ ` ` ` `... 1001 = 0000 ` ` ` ` ` ` 1111 ` ` 1111 ` `... 1111 ` ` ` ` 0110

Note that the bitwise operator “not” inverts all 32 bits, and that the highest (leftmost) bit of the value is 1, which indicates a negative number (2-complement notation).

Shift operator

The shift operator takes two operands: the first is the number to be shifted, and the second is the number that specifies how many bits to shift the first number. The direction of the shift is controlled by the operator.

The shift operator converts the operand to a 32bit integer and yields a value of the same kind as the number to be shifted.

The list of shift operators is as follows.

Shift operator

The operator describe sample
<<(Left shift) Moves the first operand to the left by a specified number of bits. The left side is moved out of position and discarded. The ones on the left are discarded. The extra space on the right is filled by zeros 9<<2 produces 36, because 1001 shifts 2 bits to the left to 100100, which is 36.
>>(Moved right with sign) Moves the first operand a specified number of bits to the right. The right shift is discarded. The extra space on the left is filled by the leftmost digit of the original value. 9>>2 produces 2, because 1001 shifts 2 bits to the right to 10, which is 2. Likewise, -9>>2 produces -3, since the sign is preserved.
>>>(Zeroing right shift) Moves the first operand a specified number of bits to the right. The right shift is discarded. The extra space on the left is filled by zeros. 19 > > > 2It produces 4, because 10011 shifts by 2 to the right to 100, so it’s 4. For nonnegative values, the right shift of the complement zero and the signed right shift produce the same result.

Logical operator

Logical operators are used between Boolean values; When the operands are Boolean, the return value is also Boolean. But in fact && and | | returns a specific value of the operand, so when it is used in a Boolean value, the return value may be a Boolean value. The logical operators are described below.

Logical operator

The operator sample describe
Logic and&& expr1 && expr2 Return expr1 if expr1 can be converted to false; Otherwise, returnexpr2. so, &&When used for booleans, returns true if all operands are true; Otherwise return false.
Logic or ` ` `expr1
Logic is not (!) ! expr Return false if the operand can be converted to true; Otherwise return true. Can be converted tofalseThe value of anull.0.NaN, empty strings (“”) andundefined. (Translator’s Note: falsy)

Here is an example of the && (logical “and”) operator.

var a1 =  true && true;     // t && t returns true
var a2 =  true && false;    // t && f returns false
var a3 = false && true;     // f && t returns false
var a4 = false && (3= =4); // f && f returns false
var a5 = "Cat" && "Dog";    // t && t returns Dog
var a6 = false && "Cat";    // f && t returns false
var a7 = "Cat" && false;    // t && f returns false
Copy the code

Copy to Clipboard

Below is | | (logical “or”) operator of the sample.

var o1 =  true || true;     // t || t returns true
var o2 = false || true;     // f || t returns true
var o3 =  true || false;    // t || f returns true
var o4 = false| | -3= =4); // f || f returns false
var o5 = "Cat" || "Dog";    // t || t returns Cat
var o6 = false || "Cat";    // f || t returns Cat
var o7 = "Cat" || false;    // t || f returns Cat
Copy the code

Copy to Clipboard

The following is! Example of the (logical “not”) operator.

var n1 = !true;  / /! t returns false
var n2 = !false; / /! f returns true
var n3 = !"Cat"; / /! t returns false
Copy the code

Copy to Clipboard

Short circuit is evaluated

Evaluated as logical expressions from left to right, they are tested for possible “short circuits” using the following rules:

  • false && anything// Short-circuited to false
  • true || anything// Short-circuited to true

Logical rules to ensure that these estimates are always correct. Note that the anything part of the expression above is not evaluated, so there are no side effects.

String operator

In addition to the comparison operator, which can be used in string values, the concatenation operator (+) concatenates two string values and returns another string that is the combination of two operand strings.

These powerful operators in JS

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 undefinedCopy the code

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, even some inconsistent, the following article is a summary of the learning process, if you find mistakes, welcome to point out the message.

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