关于javascript:未定义的变量,value == false 和!value

Undefined variables, value == false versus !value

我对用javascript编写的一段非常简单的代码有问题,你能帮我一下吗?

以下是迄今为止我对javascript和变量的理解:

  • 在布尔运算中,未定义的值被计算为false。
  • 通过在比较中使用==运算符,可以询问两个值是否具有可比性,而不管它们的类型如何。

我在一个在线课程中找到了一个练习文件,我试着去做,但是我在课堂上没有得到预期的相同结果;主要的问题是,我通过"if value==false"比较这个值。}当解决方案使用"如果!值{…}

所以我决定写一个很短的代码,以便自己尝试,但我得到的结果不一。在下面的示例中,我希望此JS代码生成两个相同的警报("foo等于false"),但第一个if语句返回"foo不等于false",第二个if返回(如预期)"foo等于false"。

这就是我写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
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这两个ifs应该做同样的工作,当我尝试用第一行替换值"var foo=undefined";用"var foo=0";它按预期工作,0是另一个应该评估为false的值,或者至少这是我记忆中的值。

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


==算法(抽象等同性比较算法)不是一种简单假设结果的算法,除非您知道该算法。你需要知道它是如何工作的细节。

例如,nullundefined是一种特殊情况。它们不进行任何类型转换,除非被认为彼此相等。

否则,通常会有一个类型转换,试图将两个操作数都简化为一个公共类型。这通常是一个吨数转换。

这就是为什么:

  • null == undefined; // true

  • null == 0; // false

  • +null == '0' // true

所以,如果你知道算法是如何工作的,你就会知道,除了undefinednull之外,undefined绝不等于任何东西,但是其他不严格相等的类型可能会被强制转换成相等的类型。

因此,做if(!x)if(x==false)是完全不同的测试。

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

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

所以…

1
if(x == false)

…如果xundefined的话,确定不等于false,但如果x0甚至是"0"的话,则认为等于false

  • 0 == false; // true

  • "0" == false; // true


"未定义"不等于"假",但在尝试计算时:

1
if (undefined)

整个表达式总是错误的

更多信息:http://www.mapbender.org/javascript_-pitfalls:_-null,_-false,_-undefined,_-nan


在JavaScript中,真实性和与true的等价性是两个不同的方面。

如果...是"真的",则if (...)执行第一个语句,而不是当它们与任何其他特定值"相等"时,因此第二个条件应该是

1
2
3
4
5
if (!foo) {
  alert("foo is falsy");  // Javascript executes this row
} else {
  alert("foo is truthy");
}

javascript中有很多"错误"的值:NaN""0-0falsenullundefined。其他值均为truthy

!运算符返回false表示任何真实值,true表示任何falsy值,因此!x(x ? false : true)表示所有x值相同。


一般来说,我发现积极的结果更容易分析,几乎就好像if(!foo)是双重消极的,所以我倾向于扭转它:

1
2
3
4
5
if (foo) {
  alert("foo is something or boolean true");
} else {
  alert("foo is null, undefined or boolean false");
}

尤其是undefinednull都不是对的或错的,但是javascript可以处理一种速记,因为它是动态的。

实际上,上面的陈述是这样的:

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

首先要检查变量是否已经定义,然后如果是布尔值,则检查变量是否为真。

同时,你的错误陈述也在检验一些不同的东西:

1
2
3
4
5
if (foo == false) {
  alert("foo is populated with the boolean false");
} else {
  alert("foo is true, something else or null");
}