Ecma-262 describes a set of operators that can be used to manipulate data values, including mathematical operators (such as addition and subtraction), bitwise operators, relational operators, and equality operators. Operators in ECMAScript are unique because they can be used for a variety of values, including strings, numeric values, Bools, and even objects. When applied to objects, operators typically call valueOf() and/or toString() methods to get computable values.

1 unary operator

Operators that operate on only one value are called unary operators. The unary operator is the simplest operator in ECMAScript.

1.1 Increment/decrement operators

There are two versions: prefix and suffix. As the name implies, the prefix version precedes the variable to be manipulated, and the suffix version precedes the variable to be manipulated.

Before before + + / –

let age = 29;
++age; / / 30

/ / equivalent to the
age = aga +1;
Copy the code

Whether the prefix increment or prefix decrement operators are used, the value of the variable changes before the statement is evaluated.

let age = 30;

let anotherAge = --age + 2;

console.log(age) / / 29
console.log(anotherAge) / / 31
Copy the code

The variable anotherAge is initialized with the value of age minus 1 plus 2. Because decrement happens first, age becomes 29 and then increases by 2, resulting in 31.

After + + / –

Postfix increments and decrement occur after the statement is evaluated. In some cases, the difference doesn’t matter:

let age = 29;
age++; / / 30

/ / equivalent to the
age = aga +1;
Copy the code

However, when mixed with other operations, the difference becomes apparent

let age = 30;

let anotherAge = age-- + 2;

console.log(age) / / 29
console.log(anotherAge) / / 32
Copy the code

The variable anotherAge is initialized with the value of age plus 2 (because increments and decrement of postfix versions do not occur until the statement is evaluated), so the variable anotherAge = 30 +2 = 32

These four operators can work on any value, not just integers — strings, Bools, floating-point values, and even objects. The increment and decrement operators follow the following rules:

  1. For strings, if the string is a numeric string (for example, let a = “123”), it is first converted to the corresponding value, then the corresponding operation is performed, and the variable type becomes numeric after the operation
let a = "12";
console.log(typeof a); // string
a++;
console.log(a); / / 13
// After the operation, the variable type becomes numeric
console.log(typeof a); //number
Copy the code
  1. For strings, if the string is not a numeric string (such as let a = “hello”), the variable becomes NaN, and the variable type becomes numeric after the operation
let a = "hello";
console.log(typeof a); // string
a++;
console.log(a); // NaN
// After the operation, the variable type becomes numeric
console.log(typeof a); //number
Copy the code
  1. For Boolean values, false becomes 0 for the operation, true becomes 1 for the operation, and the variable type becomes numeric after the operation
let a = true;
console.log(typeof a); // boolean
a++;
console.log(a); / / 2
console.log(typeof a); //number
Copy the code
  1. Floating-point values, like integers, are addition and subtraction operations

  2. If it is an object, the valueOf method is called to get the value that can be manipulated. If vauleOf returns NaN, call its toString method and try again to get a value that can be manipulated

2-bit operators

The low-level operation for numbers, that is, the bits (bits) that represent data in memory. All values in ECMAScript are stored in IEEE 754 64-bit format, but bitwise operations do not apply directly to 64-bit representations. Instead, values are converted to 32-bit integers, then bitwise operations are performed, and then the result is converted to 64-bit.

Signed integers use the first 31 bits of 32 bits to represent integer values. The 32nd bit represents a numeric symbol, such as 0 for positive and 1 for negative. This bit is called the sign bit, and its value determines the format of the rest of the value.

Positive values are stored in true binary format, where each of the 31 bits represents a power of two. The first bit (called the 0th bit) represents 2 to the 0, the second represents 2 to the 1, and so on. If a bit is empty, it is filled with 0, equivalent to being ignored.

The binary format of numerical 18 to 00000000000000000000000000010010, 10010 or more concise. The latter are the five significant bits used, which determine the actual value

Negative values are stored in a binary code called the binary complement, or complement. The binary complement of a number is computed in three steps

  1. Determine the binary representation of the absolute value (e.g., for -18, determine the binary representation of 18 first);

  2. Find the complement (or inverse) of the numeric value, in other words, every 0 becomes a 1, and every 1 becomes a 0;

  3. Add 1 to the result.

eg

// The 1:18 binary 32-bit representation
0000  0000  0000  0000  0000  0000  0001  0010

// 2 Computes a complement, that is, inverts the binary value of each bit:
1111  1111  1111  1111  1111  1111  1110  1101

// 3 Finally, add 1 to the complement:
1111  1111  1111  1111  1111  1111  1110  1110
Copy the code

The binary representation of 18 is 11111111111111111111111111101110. Note that we do not have access to bit 31 (sign bit) when dealing with signed integers.

When we print a negative value as a binary string, we get an absolute value preceded by a minus sign

let num = -18;
console.log(num.toString(2)); / / - 10010
Copy the code

By default, all integers in ECMAScript are represented as signed numbers. However, unsigned integers do exist. For unsigned integers, the 32nd bit does not represent a sign because there are only positive values. Unsigned integers have a larger range than signed integers because sign bits are used to represent values.

When bitwise operators are applied to ECMAScript values, conversion takes place behind the scenes: 64-bit values are converted to 32-bit values, bitwise operations are performed, and the result is converted from 32-bit to 64-bit for storage. The whole process is treated like 32-bit values, making binary operations similar to those in other languages. However, this conversion has the odd side effect that the special value NaN and Infinity are treated as zero in in-place operations.

If the bitwise operator is applied to a non-numeric value, the Number() function is first used to convert the value to a numeric value (this process is automatic), and then the bitwise operation is applied. The end result is a number.

2.1 according to a non

Bitwise non-operators are represented by the tilde (~), which returns the complement of a numeric value. Bitwise is one of the few binary mathematical operators in ECMAScript

let num1 = 25;      / / binary 00000000000000000000000000011001
let num2 = ~num1;   / / binary 11111111111111111111111111100110
console.log(num2);  / / - 26
Copy the code

The bitwise non-operator applies the value 25 and results in -26. As you can see, the final effect of bitwise non is to invert the value and subtract 1, as if we had done the following:

let num1 = 25;
let num2 = -num1 - 1;
console.log(num2);   / / "- 26"
Copy the code

Although both return the same result, bitwise operations are much faster. This is because bitwise operations are done on the underlying representation of the value.

2.2 the bitwise and

The bitwise and operator is represented by an ampersand (&) and has two operands. Bitwise and is essentially aligning each bit of two numbers and then performing the appropriate and operation on each bit based on the rules in the truth table.

let result = 25 & 3;
console.log(result); / / 1
Copy the code
25 = 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 --------------------------------------------- AND = 0000 0000 0000 0000 0000 0000 0000 0001Copy the code

Bitwise or 2.3

The bitwise or operator with a pipe (|), said the bitwise or operator returns 1 when at least one is 1, the two are 0 returns 0.

2.4 Bitwise XOR

Bitwise xor is represented by a broken character (^). Bitwise xor differs from bitwise or in that it returns 1 only if one digit is 1 (0 if both digits are 1 or 0).

2.5 the left

The left-shift operator, represented by two less-than signs (<<), moves all the bits of a value to the left by the specified number of bits. For example, if the number 2 (binary 10) moves five bits to the left, you get 64 (binary 1000000)

let oldValue = 2;              // is binary 10
let newValue = oldValue << 5;  // is equal to binary 1000000, that is, decimal 64
Copy the code

Pay attention to

  1. After the shift, the right end of the value will be left 5 bits empty. The left shift fills these Spaces with 0, making the result a full 32-bit value
  2. A left shift preserves the sign of the value it manipulates. For example, if you move negative 2 5 places to the left, you get negative 64 instead of positive 64.

2.6 Symbols move to the right

A signed right shift, indicated by two greater than signs (>>), moves all 32 bits of a value to the right while preserving the sign (positive or negative). A signed shift to the right is actually the inverse of a shift to the left. For example, if you move 64 five places to the right, you get 2

Again, there’s a vacancy after the shift. However, after a right shift, the space appears to the left, after the sign bit. ECMAScript fills these gaps with the value of the symbol bits to get the full value.

2.7 Unsigned right shift

An unsigned right shift, represented by three greater than signs (>>>), shifts all 32 bits of the value to the right. For positive numbers, an unsigned right shift is the same as a signed right shift. So again, if you move the sign to the right, if you move 64 5 places to the right, it becomes 2

For negative numbers, sometimes the difference can be huge. Unlike a signed right shift, an unsigned right shift adds 0 to the empty space regardless of the sign bit.

  • For positive numbers, this is the same effect as a sign shift to the right.
  • But for negative numbers, it’s too bad. The unsigned right-shift operator treats the binary representation of a negative number as the binary representation of a positive number. Because a negative number is the double complement of its absolute value, it gets really big when you move it to the right

Such as: the binary representation of 64 is 11111111111111111111111111000000, unsigned right shift but will it as a positive, which is 4, 294, 967, 232. The value moves to the right after five, the result is 00000111111111111111111111111110, 134, 217, 726.

let oldValue = -64;              / / equal to binary 11111111111111111111111111000000
let newValue = oldValue >>> 5;   // Is equal to the decimal 134217726
Copy the code

Boolean operator

There are three Boolean operators: logical not, logical and logical or.

3.1 the logical not

Logical non-operators consist of an exclamation mark (!). Can be applied to any value in ECMAScript. This operator always returns a Boolean, regardless of the data type being applied. A logical nonoperator first converts the operand to a Boolean value and then inverts it.

  • Return false if the operand is an object
  • Returns true if the operand is an empty string
  • Return false if the operand is a non-empty string
  • Returns true if the operand is 0
  • If the operand is non-zero, return false
  • Returns true if the operand is Null
  • Return true if the operand is NaN
  • Returns true if the operand is undefined
console.log(!false);   // true
console.log(!"blue");  // false
console.log(!0);       // true
console.log(!NaN);     // true
console.log(!"");      // true
console.log(!12345);   // false
Copy the code

Logical non-operators can also be used to convert arbitrary values to Booleans. Use two exclamation points (!!) at the same time , equivalent to calling the transformation function Boolean(). Regardless of the type of operand, the first exclamation mark always returns a Boolean value. The second exclamation mark reverses the Boolean value, giving the true Boolean value of the variable. The result is the same as using the Boolean() function on the same value

3.2 logic and

Logic and operators are represented by two ampersand signs (&&)

Logic and operators can be used for any type of operands, not just booleans. If an operand is not a Boolean, the logical and does not necessarily return a Boolean

  • Return the second operand if the first operand is an object
  • If the second operand is an object, true is returned only if the first operand evaluates to true
  • Return the second operand if the first two operands are objects
  • If an operand is Null, Null is returned
  • If an operand is NaN, return NaN
  • If an operand is undefined, return undefined

The logical and operator is a short-circuit operator, meaning that if the first operand determines the result, the second operand is never evaluated.

For logic and operators, if the first operand is false, the result cannot be true regardless of the value of the second operand.

The following example illustrates that the logical and operator is a short-circuit operator

let found = true;
let result = (found && someUndeclaredVariable); // There will be an error
console.log(result); // This line will not be executed
Copy the code

Because someUndeclaredVariable is not declared beforehand, an error is reported when the logic and operator evaluate it. If the found variable has a value of false, no errors will be reported

let found = false;
let result = (found && someUndeclaredVariable);  // No errors
console.log(result);  / /
Copy the code

Console. log will execute successfully. Even if the variable someUndeclaredVariable is not defined, since the first operand is false, the logic and operator will not evaluate it, because it makes no sense to evaluate the operand to the right of &&.

3.3 the logical or

Logic or the operator by two pipe (| |) said

  • Returns the first operand if the first operand is an object
  • If the first operand evaluates to false, return the second operand
  • Returns the first operand if the first two operands are objects
  • If an operand is Null, Null is returned
  • If an operand is NaN, return NaN
  • If an operand is undefined, return undefined

Logic or operators are also short-circuited. Only for logic, if the first operand evaluates to true, the second operand will not be evaluated

let found = true;
let result = (found || someUndeclaredVariable); // No errors
console.log(result); / /
Copy the code

The variable someUndeclaredVariable is also undefined. However, because the variable found has a value of true, the logic or operator does not evaluate the variable someUndeclaredVariable, but simply returns true. If you change the value of found to false, an error will be reported

Using this behavior, you can avoid assigning a variable to null or undefined

let myObject = preferredObject || backupObject;
Copy the code

In this example, the variable myObject is given one of two values. The preferredObject variable contains the preferred value and the backupObject variable contains the alternate value. If the preferredObject is not null, its value is assigned to myObject; If the preferredObject is null, the value of backupObject is assigned to myObject.

The 4 multiply/divide/mod operator

ECMAScript defines three multiplication operators: multiplication, division, and modulo. These operators do what their Java, C, and Perl counterparts do, but they also include some automatic type conversions for non-numeric values.

4.1 Multiplication operator

The multiplication operator is represented by an asterisk (*) and can be used to compute the product of two numeric values.

  • If the operands are all numeric, then do the mathematical multiplication
  • If any of the numbers is NaN, NaN is returned
  • If it’s Infinity times 0, NaN is returned
  • If Infinity is multiplied by a finite number that is not zero, then Infinity or -infinity is returned based on the sign of the second operand
  • Infinity times Infinity is Infinity
  • If not, the Number function is called, converted to a Number, and the above rules apply

4.2 Division operators

The division operator, represented by a slash (/), calculates the quotient of the first operand divided by the second operand

  • If the operands are all numeric, then divide mathematically
  • If any of the numbers is NaN, NaN is returned
  • Infinity divided by Infinity is Infinity
  • 0 divided by 0, Infinity
  • If a nonzero finite number is divided by 0, Infinity or -infinity is returned based on the sign of the first operand
  • If it’s Infinity divided by a finite number, it returns Infinity or -infinity based on the sign of the second operand
  • If not, the Number function is called, converted to a Number, and the above rules apply

4.3 Module fetch operator

The modulo (remainder) operator is represented by a percentage symbol (%)

  • If the operands are all numeric, then do the math of the mod
  • If the dividend is infinite and the divisor is finite, return NaN
  • If the dividend is finite and the divisor is 0, return NaN
  • Returns the dividend if the dividend is finite and the divisor is infinite
  • Infinity % Infinity, then NaN is returned
  • If the dividend is 0 and the divisor is not 0, return 0
  • If not, the Number function is called, converted to a Number, and the above rules apply

5 Index operator

ECMAScript 7 adds the index operator, math.pow () now has its own operator **

console.log(Math.pow(3.2);    / / 9
console.log(3* *2);           / / 9

console.log(Math.pow(16.0.5); / / 4
console.log(16支那0.5);         / / 4
Copy the code

The index operator also has its own index assignment operator *=

let squared = 3;
squared **= 2;
console.log(squared); / / 9

let sqrt = 16;
sqrt **= 0.5;
console.log(sqrt); / / 4
Copy the code

Add/subtract operators

6.1 Addition Operators

If both operands are numeric, the addition operator performs addition and returns the result according to the following rules:

  • How to return NaN if one of the operands is NaN
  • Infinity + Infinity returns Infinity
  • -infinity + -infinity returns -infinity
  • -infinity + Infinity, how to return NaN

If one of the operands is a string, the following rule applies:

  • If both are strings, it’s a string concatenation
  • If one is a string, convert the other to a string and concatenate it
  • If any of the operands are objects, values, or booleans, their toString() method is called to get the string, and the previous string rules apply. For undefined and null, the String() function is called to get “undefined” and “null”, respectively.
let result1 = 5 + 5;        // Two values
console.log(result1);       / / 10
let result2 = 5 + "5";      // A numeric value and a string
console.log(result2);       / / "55"
Copy the code

6.2 Subtraction operators

If both operands are numeric, the operator performs subtraction and returns the result according to the following rules:

  • If one of the operands is NaN, return NaN
  • Infinity – Infinity, returns NaN
  • -infinity – -infinity, returns NaN
  • Infinity — Infinity, returns Infinity
  • -infinity-infinity, return -infinity
let result1 = 5 - true; // True is converted to 1, so the result is 4
let result2 = NaN - 1;  // NaN
let result3 = 5 - 3;    / / 2
let result4 = 5 - "";   // "" is converted to 0, so the result is 5
let result5 = 5 - "2";  // "2" is converted to 2, so the result is 3
let result6 = 5 - null; // null is converted to 0, so the result is 5
Copy the code

7 Comparison operator

Performs the operations that compare two values, including less than (<), greater than (>), less than or equal to (<=), and greater than or equal to (>=), as we learned in math class. All of these operators return a Boolean value

An interesting phenomenon occurs when two strings are compared using the relational operator. Many people think that less means “alphabetically forward” and greater means “alphabetically backward,” but that’s not the case. In the case of strings, the relational operator compares the encoding of the corresponding characters in the string, which are numeric values. After the comparison, a Boolean value is returned. The point is that the encoding of uppercase letters is smaller than that of lowercase letters, so something like this can happen:

let result = "Brick" < "alphabet"; // true
Copy the code

Another strange phenomenon occurs when comparing two numeric strings, as in the following example:

let result = "23" < "3"; // true
Copy the code

This returns true when comparing the strings “23” and “3”. Because both operands are strings, their character encodings are compared one by one (the encoding for character “2” is 50, and the encoding for character “3” is 51).

If one of the operands is a value, the result of the comparison: this time the string “23” is converted to the value 23, and then compared to 3

let result = "23" < 3; // false
Copy the code

Whenever a numeric value is compared to a string, the string is converted to a numeric value and then compared to a numeric value. For numeric strings, this ensures that the result is correct. But what if strings can’t be converted to numbers:

let result = "a" < 3; // Since "a" is converted to NaN, the result is false
Copy the code

Because the character “a” cannot be converted to any meaningful value, it can only be converted to NaN. There is a rule that any relational operator returns false when it involves comparing NaN.

In most comparison scenarios, if one value is not less than another, it must be greater than or equal to it. But when comparing nans, whether less than or greater than or equal to, the result of the comparison returns false.

let result1 = NaN < 3;  // false
let result2 = NaN> =3; // false
Copy the code

8 The equality operator

The equality and inequality operators in ECMAScript originally performed type conversions before comparisons, but it was quickly questioned whether such conversions should happen at all. Finally, ECMAScript provides two sets of operators. The first group is equal and not equal, and they perform the conversion before the comparison. The second group is congruent and incongruent, which do not perform the conversion before the comparison.

8.1 Equals and does not equal

The ECMAScript equal operator is represented by two equals signs (==) and returns true if the operands are equal. The unequal operator uses an exclamation mark and an equal sign (! =) means that true is returned if the operands are not equal. Both operators perform a cast (often called a cast) before determining whether the operands are equal.

Special:

  1. When an object is compared to another type, the valueOf method of the object is first called to make the comparison
  2. Undefined is equal to null
  3. Return false as long as one of the operands is NaN; NaN ! = NaN
  4. If you’re comparing two objects, you’re comparing their address values

8.2 Congruence and incongruence

The congruence and incongruence operators are similar to the equality and inequality operators, except that they do not convert operands when comparing equality. The congruence operator is represented by three equals signs (===) and returns true only if the two operands are equal without conversion

let result1 = ("55"= =55);   // true, equal after conversion
let result2 = ("55"= = =55);  // false, unequal because of different data types
Copy the code

The incongruent operator uses an exclamation mark and two equals signs (! ==) returns true only if the two operands are not equal without the conversion.

let result1 = ("55"! =55);  // false, equal after conversion
let result2 = ("55"! = =55); // true, not equal, because the data type is different
Copy the code

Although null == undefined is true (because the two values are similar), null === undefined is false because they are not of the same data type.