Equality operators in JavaScript

18 Sep, 2016JavaScript

[] == ![]

The result is true, which means that the equation is true

Someone has already answered this, but has not given an explanation yet, here I will write it in detail:

First, explain why this code is amazing: we all know that the only non-reflexive value in JavaScript is NaN, and at first glance here, ordinary literal empty arrays are actually "non-reflexive" "Anti", isn't it contradictory? In addition, this "equation" looks like an emoji in non-monospaced font []==![]

This problem should be regarded as a bad part of JavaScript in some people's eyes, but it is helpful to understand this problem to understand the forced type conversion of JS, and you can avoid similar problems in your own code.

It takes at least four sentences to explain this "equation", involving JavaScript's operator precedence, loose equality (ie ==) judgment process, and forced type conversion

  1. There is! On the right side of the equal sign, and the priority is higher than ==, and the result on the right side is calculated first. [] is a non-false value (for reference, what is a false value: Falsy-Glossary), so the result of the operation on the right is false, which is:

    ![] ==> false // Here is the conversion process, the same below
  2. If there is a boolean value on either side of ==, first convert this value to number type, and convert the right side to 0, that is:

    Number(false) ==> 0
  3. When the two sides of == are values ​​of type number and object respectively, to convert object to number type, you need to perform a ToNumber operation on object, namely:

    Number([].valueOf()) ==> 0
  4. At this point, the values ​​on both sides of == have become 0, which is obviously true

The problem comes from the Types & Grammar part of the book You don't know JS: [You-Dont-Know-JS/ch4.md at master · getify/You-Dont-Know-JS · GitHub](https://github .com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch4.md#the-crazy-ones) (Chinese "Javascript You Don't Know (Middle Volume)")

The book lists loose and detailed judgments and forced transfer rules, but there is no specific answer to this question, so I will write it.

=== Update 2016-09-17 ===

Regarding whether the original equation can be equivalent to (comment area @宋一喵 proposed):

new Array() != new Array()

It's not possible here

First of all, == (relaxed equal, and its relative!=) and === (strictly equal, and its relative!==) when judging the value of two object types, the working principle is the same, both are Determine whether two objects point to the same value (in other words, the address is the same)

In new Array() != new Array(), or new Array() !== new Array(), two objects are compared, and there is no coercion between them. However, the right side of the original equation has a higher priority!, So the original equation is equivalent to new Array() != false, and a type conversion is necessary to compare.

In addition, there is a pitfall in loose equality, that is, most object objects include empty literal objects {}. When compared with the value of type number that appears during the coercion process, the value of object will be converted to NaN, which is comparable to any value. Are not equal. And when compared with a string, it will be converted to "[object Object]"

Number({}) ==> NaN // This represents the conversion process, this equation does not hold
Number.isNaN(Number({})) // true

{} == "[object Object]" // true
{} == 0 // false seems obvious, but it is actually NaN != 0

=== Update 2016-09-18 ===

Regarding whether this question is It's not a bug. It's a feature (proposed by @何志宇 in the comment area)

The ECMAScript specification stipulates loose equality judgment rules (refer to: ECMAScript Language Specification). Since this equation is a conversion and judgment in strict accordance with the specification, it cannot be said to be a bug in the JavaScript engine

Then someone will ask again. Since this problem is so painful, it is almost never used in actual programming, why not directly shield these special cases. Please read the following extended reading and think for yourself summary

Divergent thinking: Is the accuracy of floating-point numbers a bug or a feature?

0.1 + 0.2 != 0.3

Powered by Gatsby. Theme inspired by end2end.

© 2014-2021. Made withby mdluo.