2012-01-04 116 views
26

我用JavaScript编写的一段非常简单的代码存在问题,请问您能帮我些忙吗?未定义的变量,值== false与!值

这里就是我想我已经明白到目前为止关于JavaScript和变量:

  • 一个未定义的值进行评估,以虚假的布尔运算
  • 通过在比较 - 使用==操作符,你”重新询问两个数值是否具有可比性,无论他们的类型如何

我在网上课程中发现了一个练习文件,我尝试这样做,但是我没有得到本课中预期的相同结果;主要的问题是我通过“if value == false {...}”来比较值,而解决方案使用“if!value {...}”

所以我决定写一个非常短的代码,以便自己尝试,但我得到了不同的结果。在下面的例子中,我期望这个JS代码生成两个相同的警报(“foo等于false”),但是第一个if语句返回“foo不等于false”,而第二个if返回(如预期的那样) “foo等于假”。

这是我写的东西:

var foo = undefined; 

if (foo == false) { 
    alert("foo is equal to false"); 
} else { 
    alert("foo is not equal to false"); // Javascript executes this row 
} 

if (!foo) { 
    alert("foo is equal to false"); // Javascript executes this row 
} else { 
    alert("foo is not equal to false"); 
} 

AFAIK的双中频应该做同样的工作,逸岸当我试图在第一线的值替换“变种富=不确定;”用“var foo = 0;”它按预期工作,0是另一个应该被评估为假的值,或者至少这是我记得的。

你能告诉我我做错了什么吗?

+4

那是因为不等于'FALSE'。然而,undefined是falsey所以'undefined' - > true – Raynos 2012-01-04 17:07:44

+1

等于false和“falsey”之间的区别是什么? – Cesco 2012-01-04 17:16:46

+2

如果相等然后'x ==虚假'如果虚假然后'!x == true' – Raynos 2012-01-04 17:17:16

回答

28

==算法Abstract Equality Comparison Algorithm不是你可以简单地假设一个结果,除非你知道算法。你需要知道它是如何工作的细节。

例如,nullundefined是特例。除了认为彼此相等之外,他们不做任何类型转换。

否则,通常会有一种类型转换尝试将两个操作数都减少为一个通用类型。这通常会以转换为转换。

这就是为什么:

  • null == undefined; // true

  • null == 0; // false

  • +null == '0' // true

所以,如果你知道算法如何工作,你知道undefined绝不等于除undefinednull以外的任何其他类型,但其他不完全相同的类型可能会被强制降为相同的类型。

这样做if(!x) vs if(x==false)是完全不同的测试。

  • if(!x)执行toBoolean转换。

  • if(x == false)使用复杂的算法来决定正确的转换。

所以......

if(x == false) 

...如果xundefined,它被确定为不等于false,但如果x0甚至"0",将被视为等于false

  • 0 == false; // true

  • "0" == false; // true

+1

非常感谢你,现在我开始明白我的错误 – Cesco 2012-01-04 17:55:43

+1

是否有任何地方找到它的复杂算法是什么,或者它是如何工作的细节?你能解释一下吗? – mrReiha 2015-06-16 08:17:38

+2

@mrReiha:这些都在ECMAScript语言规范中详细说明。这里有一个链接到[抽象平等比较算法](https://es5.github.io/#x11.9.3) – 2015-06-16 11:34:49

4

真相与等价与true是在JavaScript两回事。

if (...)执行的第一条语句,如果...是“truthy”,而不是当他们是“平等”到任何其他特定值,那么你的第二个条件应该像

if (!foo) { 
    alert("foo is falsy"); // Javascript executes this row 
} else { 
    alert("foo is truthy"); 
} 

有相当JavaScript中的几个“falsy”值:NaN,"",0,-0,false,nullundefined。所有其他值是truthy

!运算符返回false任何truthy值和true任何falsy值,所以!x相同(x ? false : true)所有x

+0

非常感谢你 – Cesco 2012-01-04 17:56:21

3

一般来说我发现积极的结果更易于解析,仿佛if(!foo)是双负,所以我倾向于把它周围:

if (foo) { 
    alert("foo is something or boolean true"); 
} else { 
    alert("foo is null, undefined or boolean false"); 
} 

特别是两个undefinednull不是真或假,但JavaScript可以处理一种简写,因为它是动态的。

真的在上面的语句是一样的东西:

if (foo != null && (foo.constructor !== Boolean || foo == true)) { 
    alert("foo is something or boolean true"); 
} else { 
    alert("foo is null, undefined or boolean false"); 
} 

你第一次的变量定义,然后检查,如果是布尔值,它是真实的。

同时您的虚假陈述被检查不同的东西:

if (foo == false) { 
    alert("foo is populated with the boolean false"); 
} else { 
    alert("foo is true, something else or null"); 
} 
+0

谢谢你的澄清 – Cesco 2012-01-04 17:52:04

+1

'“foo为空,未定义或布尔值false” '或+/- 0或NaN或空字符串。 – 2012-01-04 18:30:13