我是 JavaScript 的新手,我刚刚发现了我无法理解的奇怪行为:
var magicVar = Math.sin;
magicVar == true; // it returns false
magicVar === true; // it returns false
if (magicVar) console.log("???"); // it prints "???"
发生了什么事?
谢谢。
最佳答案
var magicVar = Math.sin;
从这里开始,magicVar
是对 Math.sin
函数的引用,它实际上是一个 Object
(参见 MDN 上的 Function )
The Function constructor creates a new Function object. In JavaScript every function is actually a Function object.
magicVar == true; // it returns false
这是 false
:来自 Equality comparison and sameness在 MDN 上,如果您使用 ==
运算符比较 Object
类型的操作数与 Boolean
类型的操作数,您总是得到 false
(查看使用== 表的松散相等)。
[编辑] 正如 Bergi 在评论中指出的那样,在某些情况下,您实际上可以拥有与返回 true 的 bool 值松散比较的对象。
幕后实际发生的是 ES6 §7.2.12 中描述的比较算法。已应用。
7.2.12 Abstract Equality Comparison
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- ReturnIfAbrupt(x).
- ReturnIfAbrupt(y).
- If Type(x) is the same as Type(y), then Return the result of performing strict Equality Comparison x === y.
- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
- If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).
- If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
- Return false.
在你的情况下会发生什么:
magicVar == true
magicVar == Number(true) // Step 9. x == ToNumber(y).
magicVar == 1
toPrimitive(magicVar) == 1 // Step 11. ToPrimitive(x) == y.
magicVar.toString() == 1
"function sin() { [native code] }" == 1
Number("function sin() { [native code] }") == 1 // Step 7. ToNumber(x) == y.
NaN === 1 // Step 3. x === y.
false
但是例如与这样的对象进行比较:
{
valueOf: function(){
return 1;
}
}
你会得到:
true == {valueOf(){return 1;}} // it returns true
magicVar === true; // it returns false
这通常是 false
,操作数的类型不同,===
运算符检查操作数是否具有相同的类型和值。
if (magicVar) console.log("???"); // it prints "???"
正如所有其他答案所说,magicVar
是在 Boolean
上下文中并被强制为 true
关于Javascript 真/假函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31606348/