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

时间:2011-10-02 07:40:08

标签: javascript implicit-conversion comparison-operators

代码:

var num = 20;

if(num == "20")
{
    alert("It works");
}
else
{
    alert("Not working");
}

问题:

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

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

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

5 个答案:

答案 0 :(得分:19)

是的,equals运算符应用的所有类型转换规则都在The Abstract Equality Comparison Algorithm的ECMA-262规范中进行了描述。

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

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

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

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

    • 对对象执行对象到原始的转换并再次进行比较
  4. Object-to-Primitive转换是通过名为ToPrimitive的抽象操作完成的,此方法将尝试使用内部[[PrimitiveValue]]方法将对象转换为原始值。

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

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

    1 == { toString:null } // TypeError!
    

    上面的语句将生成TypeError,因为默认的Object.prototype.valueOf方法除了实际上相同的对象实例(this,而不是原始值)之外什么都不做,我们是设置一个不属于函数的自己的toString属性。

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

答案 1 :(得分: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.

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

答案 2 :(得分:2)

避免在JavaScript中进行隐式类型转换。在比较之前,请始终采取措施测试和/或转换单个值,以确保您将苹果与苹果进行比较。始终显式测试undefined以确定值或属性是否具有值,使用null指示对象变量或属性不引用任何对象,并转换&比较所有其他值以确保对相同类型的值执行操作。

答案 3 :(得分:0)

我知道问题已得到解答。我在下面给出的是几个转换的例子。对于刚接触JavaScript的人来说,这将非常有用。以下输出可以与通用算法进行比较,以便于理解。

代码:

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "",
          "       ",
          null,
          undefined,
          true,
          false,
          "true",
          "false"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];
    console.log("Start");
    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" !!x = " + !!x);
    console.log("End");
}

输出:

"Start"
"123"
" Number(x) = 123"
" parseInt(x, 10) = 123"
" parseFloat(x) = 123"
" +x = 123"
" !!x = true"
"End"

"Start"
undefined
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = false"
"End"

"Start"
"not a number"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

"Start"
"123.45"
" Number(x) = 123.45"
" parseInt(x, 10) = 123"
" parseFloat(x) = 123.45"
" +x = 123.45"
" !!x = true"
"End"

"Start"
"1234 error"
" Number(x) = NaN"
" parseInt(x, 10) = 1234"
" parseFloat(x) = 1234"
" +x = NaN"
" !!x = true"
"End"

"Start"
""
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
"       "
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = true"
"End"

"Start"
null
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
undefined
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = false"
"End"

"Start"
true
" Number(x) = 1"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 1"
" !!x = true"
"End"

"Start"
false
" Number(x) = 0"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = 0"
" !!x = false"
"End"

"Start"
"true"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

"Start"
"false"
" Number(x) = NaN"
" parseInt(x, 10) = NaN"
" parseFloat(x) = NaN"
" +x = NaN"
" !!x = true"
"End"

答案 4 :(得分:0)

最好使用下面的代码来理解隐式转换。

&#13;
&#13;
SET /p USERNAME=Enter Your Name:
ECHO %USERNAME%
&#13;
&#13;
&#13;