我是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构造函数创建一个新的Function对象。在JavaScript中每个函数实际上都是一个function对象。
magicVar == true; // it returns false
这是false
:从MDN上的相等比较和相同,如果您使用==
操作符比较Object
类型的操作数与Boolean
类型的操作数,您总是得到false
(使用==表查看松散相等)。
[EDIT]正如Bergi在注释中指出的那样,实际上在某些情况下,可以将对象松散地与布尔值进行比较,返回true。
在幕后实际发生的是ES6§7.2.12中描述的比较算法被应用。
7.2.12抽象相等比较比较x == y,其中x和y为值,产生真或假的。这样的比较执行如下:
- ReturnIfAbrupt (x)
- ReturnIfAbrupt (y)。
- 如果Type(x)与Type(y)相同,则返回执行严格相等比较的结果x === y
- 如果x为空且y未定义,则返回true。
- 如果x未定义且y为null,则返回true。
- 如果Type(x)为Number, Type(y)为String,返回比较结果x == Number(y)
- 如果Type(x)为String, Type(y)为Number,返回比较结果Number(x) == y
- 如果Type(x)为布尔值,则返回比较的结果number (x) == y
- 如果Type(y)为Boolean,则返回比较结果x == tonnumber (y)。
- 如果Type(x)是String, Number或Symbol, Type(y)是Object,则返回比较的结果x == topprimitive (y)。
- 如果Type(x)是Object, Type(y)是String, Number, or Symbol,那么返回比较的结果topprimitive (x) == y。
- 返回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
magicVar
是true 作为值。它是真的,因为它不是空的,它不是空的或未定义的。任何非空值都是真值。但是这个值等于为true吗?不。作为布尔值为真,而作为值为真。
总结:
magicVar == true || magicVar === true; // returns false
Boolean(magicVar); // returns true
这里要掌握的概念是与真布尔值和假布尔值相比,真值和假值之间的区别。真见这里,假见这里
长话短说,如果表达式为真,则if
条件通过,并且magicVar
是function
(真)。
magicVar不等于true。它等于数学。罪功能。
因此,在if语句中,它被求值为真值(它是定义的,不会求值为假值)。
http://www.sitepoint.com/javascript-truthy-falsy/比较function Math.sin
和boolean
常量返回false
,因为这个变量有不同的类型。但是,当您将非bool变量放入if
条件时:例如if (Math.sin)...
或if (window)...
,如果变量不等于null,则返回true。