美文网首页
类型转换

类型转换

作者: good__day | 来源:发表于2019-03-17 21:01 被阅读0次

    本文转载自: https://www.h5jun.com/post/why-false-why-true.html

    问题:为什么 [ ] == false,而 !![ ] == true?

    这是一个很有迷惑性的问题。咋一看,不可能啊?如果 [ ] == false,那么 !![ ] 相当于 !!false,难道不是为 false 吗,为什么会是 true 呢?会不会是引擎 bug,搞错了?

    console.log([] == false, !![] == true); // true, true

    事实上不是 bug,这与 ECMA 规范和类型转换有关。我们知道,非严格比较操作符 == 是会做强制类型转换的,那么根据 ECMA 262 它的规则是:

    来源:http://www.ecma-international.org

    注意一下:

    第 7 条:If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

    第 9 条:If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.

    所以 [] == false 的比较是 ToNumber(false) (为 0),然后和对 x 执行 ToPrimitive(x) 进行比较。

    看一下 ToPrimitive:

    来源:http://www.ecma-international.org

    来源:http://www.ecma-international.org

    来源:http://www.ecma-international.org

    根据上面的规则对于 ToPrimitive([ ]),先执行 [].valueOf(),返回 result 的是 [ ],因为 Type(result) 是 Object,所以继续执行 [].toString(),返回 ""。

    因此实际上最终是比较 "" == 0,结果为 true。

    再来看 !![] == true:

    按照优先级,先执行 !![],根据规范,实际上是 !!(ToBoolean([])):

    而 ToBoolean 的规则是:

    所以 ToBoolean([]) 被转成 true,!!true 自然是 true 了。

    所以这就是 [] == false 而 !![] == true 的真正原因了。这也是为什么我们不能用 if(!array) 来判断空数组而要用 if(array.length === 0)来判断空数组的原因。

    同样,还有 [0] == false 而 !![0] == true,现在你自己能分析出原因了。

    思考: []==![] //true

    首先 ![]  将 [] 转成 boolean, 此时题目为 [] == false ?

    参考标准第 7 条, 题目变为  [] == 0 ?

    参考第 9 条,题目变为 ToPrimitive([ ]) == 0 ?根据上面的规则对于 ToPrimitive([ ]),先执行 [].valueOf(),返回 result 的是 [ ],因为 Type(result) 是 Object,所以继续执行 [].toString(),返回 ""。 “” = 0? 

    返回 true

    ToPrimitive 函数,它是对象类型到基本类型转换的实现者(即,拆箱转换)  https://juejin.im/post/5c5011805188252552518470

    相关文章

      网友评论

          本文标题:类型转换

          本文链接:https://www.haomeiwen.com/subject/vtuhmqtx.html