使用==比较整数和字符串时JavaScript中的隐式数据类型转换

car*_*995 10 javascript comparison-operators implicit-conversion

代码:

var num = 20;

if(num == "20")
{
    alert("It works");
}
else
{
    alert("Not working");
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 在C编程中,我们有一个规则名称数据类型提升,当存在混合数据类型时(例如:添加整数和浮点),整数将在执行加法之前首先转换为浮点.

  2. 上面的代码将提示我一个警告框,"It works"其中显示的消息显示if测试条件评估为true.

  3. 对于松散类型的JavaScript,我只是好奇:有没有像C这样的规则决定在哪种情况下执行哪个转换?除此之外,上面的JavaScript代码num在进行比较之前将变量值从整数值转换为字符串值,反之亦然?

CMS*_*CMS 20

是的,equals运算符应用的所有类型转换规则都在ECMA-262规范的抽象等式比较算法中描述.

该算法看起来可能非常复杂,但可归纳为以下情况:

  1. 两个操作数的类型是相同的:

    • 对于基元(String,Number,Boolean,Null,Undefined)
      • 如果值完全相同,则返回true
    • 对于Object类型
      • 如果两个引用指向同一个对象,则返回true
  2. 如果两个操作数的类型不同

    • 如果一个操作数的类型是Null或Undefined
      • 仅当另一个操作数值为null或时,才返回trueundefined
    • 如果其中一个操作数的类型为Boolean或Number
      • (在一些步骤之后)将另一个操作数转换为Number并进行比较
  3. 如果其中一个操作数是Object而另一个是原语

    • 对Object执行Object-to-Primitive转换并再次进行比较

Object-to-Primitive转换是通过调用的抽象操作进行的ToPrimitive,此方法将尝试使用内部[[PrimitiveValue]]方法将对象转换为原始值.

这将尝试执行对象valueOftoString方法,并将获取返回原始值的第一个值.

如果这两个方法不返回原语,或者它们不可调用,TypeError则抛出a,例如:

1 == { toString:null } // TypeError!
Run Code Online (Sandbox Code Playgroud)

上面的语句将产生一个TypeError因为默认Object.prototype.valueOf方法不会做任何比实际相同的对象实例(this不是原始值)更多的东西,我们正在设置一个toString不属于函数的自己的属性.

一个朋友制作了一个可能对你感兴趣的小工具,它显示了所有步骤和类型之间的递归比较:


Ann*_*ang 6

在JavaScript中,有两个运算符可用于比较两个值:=====运算符.

引自JavaScript The Definitive Guide第6版:

等于运算符==就像严格相等运算符(===),但它不那么严格.如果两个操作数的值不是同一类型,它会尝试某些类型转换并再次尝试比较.

严格相等运算符===计算其操作数,然后按如下方式比较这两个值,不执行类型转换.

因此,我建议您===始终使用以避免以下问题:

null == undefined // These two values are treated as equal. 
"0" == 0 // String converts to a number before comparing. 
0 == false // Boolean converts to number before comparing. 
"0" == false // Both operands convert to numbers before comparing.
Run Code Online (Sandbox Code Playgroud)

PS我可以发布书中所写的整个"比较指南",但它太长了;)告诉我,我会为你编辑我的帖子.

  • 一个很好的答案,但不是问题的答案. (2认同)