使用 == 比较整数和字符串时,JavaScript 中的隐式数据类型转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7625144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implicit data type conversion in JavaScript when comparing integer with string using ==
提问by caramel1995
The code:
代码:
var num = 20;
if(num == "20")
{
alert("It works");
}
else
{
alert("Not working");
}
The question:
问题:
In C programming we have a rule name data type promotion, where when there's a mix of data type (example: addition of integer and floating point), the integer will first converted to floating point before the addition is being carry out.
The code above will prompt me an alert box with the message
"It works"
that shows theif
test condition is evaluate to true.For loosely typed JavaScript, I'm just curious: is there any rule like C that determines which conversion will be carry out in which situation? Besides that, the JavaScript code above converts
num
variable value from an integer value to string value before making comparison or vice versa?
在C编程中,我们有一个规则名称数据类型提升,当数据类型混合时(例如:整数和浮点数的加法),在执行加法之前先将整数转换为浮点数。
上面的代码将提示我一个警告框,
"It works"
其中显示if
测试条件评估为真的消息。对于松散类型的 JavaScript,我只是好奇:有没有像 C 这样的规则来确定在哪种情况下执行哪种转换?除此之外,上面的 JavaScript 代码
num
在进行比较之前将变量值从整数值转换为字符串值,反之亦然?
回答by CMS
Yes, all the rules of type conversion applied by the equals operator are described on the ECMA-262 specification, in The Abstract Equality Comparison Algorithm.
是的,等号运算符应用的所有类型转换规则都在 ECMA-262 规范的抽象相等比较算法中进行了描述。
The algorithm might look quite complex but it can be summarized to the following cases:
该算法可能看起来很复杂,但可以总结为以下情况:
The type the two operands is the same:
- For primitives (String, Number, Boolean, Null, Undefined)
- Return true if the value is exactly the same
- For the Object type
- Return true if the two references point to the same object
- For primitives (String, Number, Boolean, Null, Undefined)
If the types of the two operands differ
- If the type of one operand is either Null or Undefined
- Return true only if the other operand value is either
null
orundefined
- Return true only if the other operand value is either
- If one of the operands is of type Boolean or Number
- (after some steps) Convert the other operand to Number and compare
- If the type of one operand is either Null or Undefined
If one of the operands is an Object and the other is a primitive
- Perform Object-to-Primitive conversion on the Object and compare again
两个操作数的类型相同:
- 对于基元(字符串、数字、布尔值、空值、未定义)
- 如果值完全相同,则返回 true
- 对于对象类型
- 如果两个引用指向同一个对象,则返回 true
- 对于基元(字符串、数字、布尔值、空值、未定义)
如果两个操作数的类型不同
- 如果一个操作数的类型为 Null 或 Undefined
- 仅当另一个操作数值为
null
或时返回 trueundefined
- 仅当另一个操作数值为
- 如果操作数之一是布尔型或数字型
- (经过一些步骤后)将另一个操作数转换为 Number 并进行比较
- 如果一个操作数的类型为 Null 或 Undefined
如果一个操作数是一个对象,另一个是一个基元
- 对 Object 执行 Object-to-Primitive 转换并再次比较
The Object-to-Primitive conversion is made through an abstract operation called ToPrimitive
, this method will try to convert the object to a primitive value, using the internal [[PrimitiveValue]]
method.
Object-to-Primitive 转换是通过一个名为 的抽象操作进行的ToPrimitive
,该方法将尝试使用内部[[PrimitiveValue]]
方法将对象转换为原始值。
This will try to ejecute the object's valueOf
and toString
methods, and it will take the value of the first that returns a primitive value.
这将尝试弹出对象的valueOf
和toString
方法,并且它会取第一个返回原始值的值。
In the case those two methods don't return a primitive, or they aren't callable, a TypeError
is thrown, e.g.:
如果这两个方法不返回原语,或者它们不可调用,TypeError
则会抛出 a ,例如:
1 == { toString:null } // TypeError!
The above statement will produce a TypeError
because the default Object.prototype.valueOf
method doesn't do anything more than actually the same object instance (this
, not a primitive value) and we are setting an own toString
property that's not a function.
上面的语句将产生 aTypeError
因为默认Object.prototype.valueOf
方法除了实际相同的对象实例(this
,不是原始值)之外没有做任何事情,并且我们正在设置一个自己的toString
属性,而不是一个函数。
A friend made small tool that might be interesting to you, it shows all the steps and recursive comparisons made between types:
一个朋友制作的小工具,你可能会感兴趣,它显示了类型之间的所有步骤和递归比较:
回答by Annie Lagang
In JavaScript, there are two operators that can be used to compare two values: the ==
and ===
operators.
在 JavaScript 中,有两个运算符可用于比较两个值:==
和===
运算符。
Quoted from JavaScript The Definitive Guide 6th Edition:
引自 JavaScript 权威指南第 6 版:
The equality operator
==
is like the strict equality operator (===
), but it is less strict. If the values of the two operands are not the same type, it attempts some type conversions and tries the comparison again.
相等运算符
==
与严格相等运算符 (===
)类似,但不那么严格。如果两个操作数的值类型不同,它会尝试一些类型转换并再次尝试比较。
And
和
The strict equality operator
===
evaluates its operands, and then compares the two values as follows, performing no type conversion.
严格相等运算符
===
计算其操作数,然后按如下方式比较两个值,不执行类型转换。
So I suggest that you use ===
all the time to avoid problems like:
所以我建议你一直使用===
以避免出现以下问题:
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. I could post the entire "comparison guidelines" as written in the book but it's too long ;) Just tell me and I'll edit my post for you.
PS我可以发布书中写的整个“比较指南”,但它太长了;)告诉我,我会为你编辑我的帖子。
回答by Bill
Avoid implicit type conversion in JavaScript. Always take steps to test and/or convert individual values before comparing them to ensure you are comparing apples to apples. Always test explicitly for undefined to determine if a value or property has a value, use null to indicate that object variables or properties do not refer to any object, and convert & compare all other values to ensure operations are performed against values of the same type.
避免 JavaScript 中的隐式类型转换。在比较单个值之前,始终采取措施测试和/或转换它们,以确保您将苹果与苹果进行比较。始终显式测试 undefined 以确定值或属性是否有值,使用 null 表示对象变量或属性不引用任何对象,并转换和比较所有其他值以确保针对相同类型的值执行操作.
回答by Aravamudhan
I know the question has been answered. What I have given below is an example of few conversions. It will be useful for someone who is new to JavaScript. The below output can be compared with the general algorithm for an easy understanding.
我知道问题已经回答了。我在下面给出的是几个转换的例子。这对 JavaScript 新手很有用。为了便于理解,可以将下面的输出与通用算法进行比较。
The code:
代码:
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");
}
The output:
输出:
"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"
回答by Ratnesh Lal
Better use below code for understanding implicit conversion.
更好地使用下面的代码来理解隐式转换。
var values = [ 0 , 123, "0", "123", -0, +0, NaN, +NaN, -NaN, false, true, "false", "true", null, undefined, "null", "undefined", "", "GoodString", " "];
for (var i = 0; i < values.length; i++){
console.log("<<<<<<<<<<<<Starting comparing: " + i + ">>>>>>>>>>>>>>>");
for (var j = 0; j < values.length; j++){
console.log(values[i],`==`, values[j]);
console.log(eval(values[i] == values[j]));
}
}