Original code snippet:

var a = []
console.log(a == 0)//trueconsole.log(! a == 0)//trueCopy the code

a == 0

It’s almost executed

Number(a.toString()) == 0;
Number("") = = 0; 0 = = 0;Copy the code

! a == 0

It’s almost executed

Number(! a) == 0; Number(false) = = 0; 0 = = 0Copy the code

Knowledge point analysis

The directory is as follows:

  1. == equality operator operator rules;

  2. Abstract operation ToNumber;

  3. Abstract operation ToPrimitive;

  4. Numerically convert the Number() function;

  5. The logical not! Operation rules;

  6. Boolean value conversion.

1. Operation rules of the == equality operator

Refer to MDN and get:

The equality operator compares different types of values as follows:

In the table above, ToNumber(A) tries to convert parameter A to A number before comparing, which has the same effect as +A (the unary operator +). ToPrimitive(A) converts the argument A to its Primitive value (Primitive) by trying to call A’s a.tostring () and a.Valueof () methods in turn.

As can be seen from the table above, equality comparison with Number type is converted to Number type for comparison.

Reference link: developer.mozilla.org/zh-CN/docs/…

2. Abstract operation ToNumber

The ES5 specification defines the abstract operation ToNumber in Section 9.3.

Where true is converted to 1 and false to 0.

Undefined is converted to NaN and null to 0.

ToNumber converts strings to general rules (Number(..)) Function). NaN is returned on failure to process (a syntax error occurs on failure to process numeric constants).

Number(..) Follow the ToNumber rule to convert a value to a numeric base type.

Objects (including arrays) are first converted to the corresponding primitive type value, depending on the ToPrimitive operation, and if a non-numeric primitive type value is returned, it is then cast to a number following the above rules.

——————- from JavaScript You Don’t Know (Middle Volume)

As you can see, the abstract operation ToNumber actually behaves roughly the same as the Number() function.

3. Abstract operation ToPrimitive

The abstract operation ToPrimitive (see ES5 specification Section 9.1) first checks for the valueOf() method (via the internal operation DefaultValue, see ES5 specification Section 8.12.8).

If a primitive type value is present and returned, that value is used for the cast.

If not, the return value of toString() is used (if present) for the cast.

If neither valueOf() nor toString() returns a base type value, TypeError is generated.

——————- from JavaScript You Don’t Know (Middle Volume)

4. Numerically convert the Number() function

The conversion rules for the Number function are as follows:

  • If Boolean, true and false are converted to 1 and 0, respectively;

  • If it is a numeric value, it is simply passed in and returned;

  • If null, return 0;

  • If undefined, NaN is returned;

  • If it is a string, follow these rules:

    • If the string contains only numbers (including those preceded by a plus or minus sign), it is converted to a decimal value (the prefix 0 is ignored);

    • If the string contains a valid floating-point format, it is converted to the corresponding floating-point value;

    • If the string contains a valid hexadecimal format, convert it to a decimal integer value of the same size;

    • If the string is empty, it is converted to 0;

    • If the string contains characters other than those in the above format, it is converted to NaN.

  • If it is an object, the valueOf () method of the object is called and the returned value is converted according to the previous rules. If the result of the conversion is NaN, the object’s toString () method is called, and the string value returned is converted again from the previous conversion rules.

    ——————— from JavaScript Advanced Programming

5. Logic is not! algorithm

The operator The sample instructions
Logic and (&&) *expr1* &&*expr2* if*expr1*Can be converted intofalseIt returnsexpr1Otherwise returnexpr2. Therefore, when used with booleans, if both operands aretruewhen&&returntrueOtherwise returnfalse.
Logic or (||) *expr1* ||*expr2* ifexpr1Can be converted intotrueIt returnsexpr1Otherwise returnexpr2. Therefore, when used with booleans, if any of the operands aretruewhen
Logic is not (!) ! *expr* ifexprCan converttrueTo return tofalse; ifexprCan convertfalse, the returntrue.

— — — — — — — — — — — — from the MDN

Reference link: developer.mozilla.org/zh-CN/docs/…

6. Boolean value conversion

The data type The value converted to true Convert to a value of false
Boolean true false
String Any non-empty string An empty string
Number Any non-zero numeric value 0 and NaN
Object Any object null
undefined undefined

—————— from JavaScript Advanced Programming

conclusion

  • The congruency operator === is recommended because it does not perform implicit type conversion compared to the equality operator ==.