Javascript 未定义的变量,value == false 与 !value

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8730792/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:14:09  来源:igfitidea点击:

Undefined variables, value == false versus !value

javascript

提问by Cesco

I have a problem with a very simple piece of code written in Javascript, could you help me please?

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

Here's what I think I have understand so far about javascript and variables:

以下是我认为到目前为止我对 javascript 和变量的了解:

  • An undefined value is evaluated to false in a boolean operation
  • By using a == operator in a comparation, you're asking if two values are comparable regardless of their types
  • 在布尔运算中,未定义的值被评估为 false
  • 通过在比较中使用 == 运算符,您会询问两个值是否具有可比性,而不管它们的类型

I found an exercise file in a online course and I tried to do it, but I didn't got the same result expected in the lesson; the main problem was that I was comparing the value through a "if value == false { ... }" while the solution was using a "if !value { ... }"

我在一个在线课程中找到了一个练习文件,我试着去做,但我没有得到课上预期的结果;主要问题是我正在通过“if value == false { ... }”比较值,而解决方案使用的是“if !value { ... }”

So I decided to write a very short code in order to try it by myself, but I'm getting mixed results. Here in the example below I would expect this JS code to generate two identical alerts ("foo is equal to false"), but instead the first if statement returns "foo IS NOT equal to false" while the second if returns (as expected) "foo is equal to false".

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

This is what I written:

这是我写的:

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 the two IFs should do the same work, and infact when I tried it by replacing in the first line the value "var foo = undefined;" with "var foo = 0;" it worked as expected, and 0 is another value that should be evaluated to false, or at least this is what I remember.

AFAIK 两个 IF 应该做同样的工作,事实上,当我通过在第一行替换值“var foo = undefined;”来尝试它时 与“var foo = 0;” 它按预期工作,0 是另一个应评估为 false 的值,或者至少这是我记得的。

Could you tell me what I'm doing wrong?

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

回答by

The ==algorithm (Abstract Equality Comparison Algorithm)isn't something where you can simply assume an outcome unless you know the algorithm. You need to know the details of how it works.

==算法摘要相等比较算法是不是在那里你可以简单地假设一个结果,除非你知道的算法。你需要知道它是如何工作的细节。

For example, nulland undefinedare a special case. They do not do any type conversion other than to be considered equal to each other.

例如,nullundefined是一个特例。除了被认为彼此相等之外,它们不进行任何类型转换。

Otherwise there's typically a type conversion that tries to reduce both operands to a common type. This often ends up being a toNumberconversion.

否则,通常会进行类型转换,尝试将两个操作数都减少为公共类型。这通常最终成为toNumber转换。

That's why:

这就是为什么:

  • null == undefined; // true

  • null == 0; // false

  • +null == '0' // true

  • null == undefined; // true

  • null == 0; // false

  • +null == '0' // true

So if you know how the algorithm works, you know that undefinednever equals anything except for undefinedand null, but other types that are not strictly equal may be coerced down to types that are equal.

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

So doing if(!x)vs if(x==false)are entirely different tests.

所以做if(!x)vsif(x==false)是完全不同的测试。

  • if(!x)performs toBooleanconversion.

  • if(x == false)uses a complex algorithm to decide the proper conversion.

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

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

So with...

所以与...

if(x == false)

...if xis undefined, it is determined to not be equal to false, yet if xis 0or even "0", it will be considered equal to false.

...如果xundefined,则确定不等于false,但如果x0或什至"0",则将其视为等于false

  • 0 == false; // true

  • "0" == false; // true

  • 0 == false; // true

  • "0" == false; // true

回答by kaz

undefined does not equal to false, but when you are trying to evaulate:

undefined 不等于 false,但是当您尝试评估时:

if (undefined)

the whole expression is always false

整个表达式总是假的

more info: http://www.mapbender.org/JavaScript_pitfalls:_null,_false,_undefined,_NaN

更多信息:http: //www.mapbender.org/JavaScript_pitfalls: _null,_false,_undefined, _NaN

回答by Mike Samuel

Truth and equivalence with trueare two different things in JavaScript.

真值和等价true是 JavaScript 中的两件事。

The if (...)executes the first statement if the ...is "truthy", not when they are "equal" to any other particular value, so your second conditional should look like

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

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

There are quite a few "falsy" values in JavaScript: NaN, "", 0, -0, false, null, undefined. All other values are truthy.

JavaScript 中有不少“假”值:NaN, "", 0, -0, false, null, undefined。所有其他值都是truthy

The !operator returns falsefor any truthy value and truefor any falsyvalue, so !xis the same as (x ? false : true)for all x.

!运营商的回报false的任何truthy价值,true任何falsy价值,所以!x是一样的(x ? false : true)所有x

回答by Keith

As a general rule I find that the positive outcome is easier to parse, almost as if if(!foo)is a double-negative, so I'd tend to turn it around:

作为一般规则,我发现积极的结果更容易解析,几乎就像if(!foo)是双重否定一样,所以我倾向于扭转它:

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

In particular both undefinedand nullare not true or false, but javascript can handle a kind of shorthand because it's dynamic.

特别是undefinednull都不是真或假,但 javascript 可以处理一种速记,因为它是动态的。

Really the statement above is something like:

其实上面的语句是这样的:

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

You're checking first that the variable has been defined and then that if it is boolean that it's true.

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

Meanwhile your false statement is checking something different:

同时,您的虚假陈述正在检查不同的内容:

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