代码:
var num = 20;
if(num == "20")
{
alert("It works");
}
else
{
alert("Not working");
}
问题:
在C编程中,我们有一个规则名称数据类型提升,当存在混合数据类型时(例如:添加整数和浮点),整数将在添加之前首先转换为浮点数执行。
上面的代码会提示我一个警告框,其中显示"It works"
消息,显示if
测试条件评估为真。
对于松散类型的JavaScript,我只是好奇:有没有像C这样的规则决定在哪种情况下执行转换?除此之外,上面的JavaScript代码在进行比较之前将num
变量值从整数值转换为字符串值,反之亦然?
答案 0 :(得分:19)
是的,equals运算符应用的所有类型转换规则都在The Abstract Equality Comparison Algorithm的ECMA-262规范中进行了描述。
该算法可能看起来相当复杂,但可归纳为以下情况:
两个操作数的类型相同:
如果两个操作数的类型不同
null
或undefined
如果其中一个操作数是Object而另一个是原语
Object-to-Primitive转换是通过名为ToPrimitive
的抽象操作完成的,此方法将尝试使用内部[[PrimitiveValue]]
方法将对象转换为原始值。
这将尝试执行对象的valueOf
和toString
方法,它将获取返回原始值的第一个值。
如果这两个方法没有返回原语,或者它们不可调用,则抛出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)
最好使用下面的代码来理解隐式转换。
SET /p USERNAME=Enter Your Name:
ECHO %USERNAME%
&#13;