!! 与 == 的转换规则一样吗?

  |   0 评论   |   0 浏览   |   Erioifpud

结论是不一样,举一个例子:

'true' == true // false
!!'true' // true

可以看出执行 ==!! 操作时,会将同样的字符串 'true' 转换成不一样的结果。

接下来我们看一下 ECMAScript 的规范

==

  1. 如果 Type(x)Type(y) 类型相同, 那么
    1. 如果 Type(x)Undefined, 返回 true.
    2. 如果 Type(x)Null, 返回 true.
    3. 如果 Type(x) 是 Number, 那么
      1. 如果 x 是 NaN, 返回 false.
      2. 如果 y 是 NaN, 返回 false.
      3. 如果 x 与 y 是相同的 Number, 返回 true.
      4. 如果 x 是 +0 并且 y 是 −0, 返回 true.
      5. 如果 x 是 −0 并且 y 是 +0, 返回 true.
      6. 返回 false.
    4. 如果 Type(x)String, 那么返回 true, 如果 x 和 y 是相同的序列 (长度一样,相同下标的字符一样). 否则, 返回 false.
    5. 如果 Type(x)Boolean, 返回 true 如果 x 和 y 都是 true 或者都是 false. 否则, 返回 false.
    6. 返回 true 如果 x 和 y 引用了相同的对象 (地址). 否则, 返回 false.
  2. 如果 x 是 null 并且 y 是 undefined, 返回 true.
  3. 如果 x 是 undefined 并且 y 是 null, 返回 true.
  4. 如果 Type(x)Number 并且 Type(y)String, 返回 x == ToNumber(y) 的比较结果。
  5. 如果 Type(x)String 并且 Type(y)Number, 返回 ToNumber(x) == y 的比较结果。
  6. 如果 Type(x)Boolean, 返回 ToNumber(x) == y 的比较结果。
  7. 如果 Type(y)Boolean, 返回 x == ToNumber(y) 的比较结果。
  8. 如果 Type(x)StringNumber 并且 Type(y)Object,返回 x == ToPrimitive(y) 的比较结果。
  9. 如果 Type(x)Object 并且 Type(y)StringNumber,返回 ToPrimitive(x) == y 的比较结果。
  10. 返回 false.

简单来说,当两者类型不同,并且都为基本类型的时候,优先将他们转换成 Number 进行比较两者为基本类型与对象时,获取对象的原始值(primitive),也就是按顺序与 toStringvalueOf 的结果进行比较。

!!

先看一下 ! 操作符的行为:

  1. expr 表示 UnaryExpression 一元表达式的值。
  2. oldValue 成为 ToBoolean(GetValue(expr)).
  3. 如果 oldValuetrue, 返回 false.
  4. 返回 true.

关键在 ToBoolean 这个操作上,行为如表所示:

参数类型(ToBoolean(arg)) 结果
undefined false
null false
boolean 和传入的参数 arg 一样
number +0-0NaN 时为 false,其他情况为 true
string '' 时为 false,其他情况为 true
object true

! 操作符用于根据以上规则,将表达式结果转换为 Boolean 再取反,那么 !! 实际上是在 ! 的基础上再一次取反,所以结果就是“将表达式结果转换成 Boolean”,!! 只是一个取巧的操作。

那么可以看出,!!== 的转换规则并不同,!!不会将值优先转换成 Number,而是直接转换为 Boolean,这就和调用 Boolean() 函数的时候一样。


标题:!! 与 == 的转换规则一样吗?
作者:Erioifpud
地址:https://blog.doiduoyi.com/articles/1606275739314.html

评论

发表评论