Javascript 为什么逻辑运算符(&& 和 ||)不总是返回布尔结果?

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

Why don't logical operators (&& and ||) always return a boolean result?

javascriptlogical-operators

提问by theateist

Why do these logical operators return an object and not a boolean?

为什么这些逻辑运算符返回一个对象而不是布尔值?

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

var _ = obj && obj._;

I want to understand why it returns result of obj.fn()(if it is defined) OR obj._but not boolean result.

我想了解为什么它返回obj.fn()(如果已定义) ORobj._结果而不是布尔结果。

采纳答案by Santosh Linkha

var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 

will return boolean.

将返回布尔值。

UPDATE

更新

Note that this is based on my testing. I am not to be fully relied upon.

请注意,这是基于我的测试。我不应该被完全依赖。

It is an expression that does notassign trueor falsevalue. Rather it assigns the calculated value.

它是一个赋值true或赋值的表达式false。而是分配计算值。

Let's have a look at this expression.

我们来看看这个表达式。

An example expression:

一个示例表达式:

var a = 1 || 2;
// a = 1

// it's because a will take the value (which is not null) from left
var a = 0 || 2;
// so for this a=2; //its because the closest is 2 (which is not null)

var a = 0 || 2 || 1;    //here also a = 2;

Your expression:

你的表情:

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

// _ = closest of the expression which is not null
// in your case it must be (obj.fn && obj.fn())
// so you are gettig this

Another expression:

另一种表达:

var a = 1 && 2;
// a = 2

var a = 1 && 2 && 3;
// a = 3 //for && operator it will take the fartest value
// as long as every expression is true

var a = 0 && 2 && 3;
// a = 0

Another expression:

另一种表达:

var _ = obj && obj._;

// _ = obj._

回答by DragonLord

In JavaScript, both ||and &&are logical short-circuit operators that return the first fully-determined “logical value” when evaluated from left to right.

在 JavaScript 中,||&&都是逻辑短路运算符,当从左到右求值时,它们返回第一个完全确定的“逻辑值”。

In expression X || Y, Xis first evaluated, and interpreted as a boolean value. If this boolean value is “true”, then it is returned. And Yis not evaluated. (Because it doesn't matter whether Yis true or Yis false, X || Yhas been fully determined.) That is the short-circuit part.

在 expression 中X || YX首先计算,并解释为布尔值。如果此布尔值为“true”,则返回它。并且Y不被评估。(因为Y真假无所谓YX || Y已经完全确定了。)那就是短路部分。

If this boolean value is “false”, then we still don't know if X || Yis true or false until we evaluate Y, and interpret it as a boolean value as well. So then Ygets returned.

如果这个布尔值是“假”,那么X || Y在我们评估之前我们仍然不知道是真还是假Y,并将其解释为一个布尔值。所以然后Y被退回。

And &&does the same, except it stops evaluating if the first argument is false.

&&执行相同的操作,除了它停止评估第一个参数是否为假。

The first tricky part is that when an expression is evaluated as “true”, then the expression itself is returned. Which counts as "true" in logical expressions, but you can also use it. So this is why you are seeing actual values being returned.

第一个棘手的部分是,当表达式被评估为“真”时,则返回表达式本身。这在逻辑表达式中算作“真”,但您也可以使用它。这就是为什么您会看到返回实际值的原因。

The second tricky part is that when an expression is evaluated as “false”, then in JS 1.0 and 1.1 the system would return a boolean value of “false”; whereas in JS 1.2 on it returns the actual value of the expression.

第二个棘手的部分是,当一个表达式被评估为“false”时,那么在 JS 1.0 和 1.1 中,系统将返回一个布尔值“false”;而在 JS 1.2 中,它返回表达式的实际值。

In JS false, 0, -0, "", null, undefined, NaNand document.allall count as false.

在 JSfalse0,, -0, "", null, undefined,NaNdocument.all算作 false

Here I am of course quoting logical values for discussion's sake. Of course, the literal string "false"is not the same as the value false, and is therefore true.

在这里,我当然是为了讨论而引用逻辑值。当然,文字字符串"false"与 value 不同false,因此为真。

回答by Sam Eaton

In the simplest terms:

用最简单的话来说:

The ||operator returns the first truthy value, and if none are truthy, it returns the last value (which is a falsy value).

||运算符返回第一truthy值,并且如果没有一个是truthy,它返回最后一个值(这是一个falsy值)。

The &&operator returns the first falsy value, and if none are falsy, it return the last value (which is a truthy value).

&&运算符返回第一个假值,如果没有一个假值,则返回最后一个值(这是一个真值)。

It's really that simple. Experiment in your console to see for yourself.

真的就是这么简单。在您的控制台中进行实验以亲自查看。

"" && "Dog"    // ""
"Cat" && "Dog" // "Dog"
"" || "Dog"    // "Dog"
"Cat" || "Dog" // "Cat"

回答by evilReiko

In most programming languages, the &&and ||operators returns boolean. In JavaScript it's different.

在大多数编程语言中,&&||运算符返回布尔值。在 JavaScript 中则不同



OR Operator:

或运算符:

It returns the value of the first operandthat validates as true (if any), otherwise it returns the value of the last operand(even if it validates as false).

它返回的值,第一个操作数,用于验证为真(如果有的话),否则返回的值最后一个操作数(即使它证明为假)

Example 1:

示例 1:

var a = 0 || 1 || 2 || 3;
        ^    ^    ^    ^
        f    t    t    t
             ^
             first operand that validates as true
             so, a = 1

Example 2:

示例 2:

var a = 0 || false || null || '';
        ^    ^        ^       ^
        f    f        f       f
                              ^
                              no operand validates as true,
                              so, a = ''


AND Operator:

AND 运算符:

It returns the value of the last operandthat validates as true (if all conditions validates as true), otherwise it returns the value of the first operandthat validates as false.

它返回最后一个验证为真的操作数的值(如果所有条件都验证为真),否则返回第一个验证为 false 的操作数的值

Example 1:

示例 1:

var a = 1 && 2 && 3 && 4;
        ^    ^    ^    ^
        t    t    t    t
                       ^
                       last operand that validates as true
                       so, a = 4

Example 2:

示例 2:

var a = 2 && '' && 3 && null;
        ^    ^     ^    ^
        t    f     t    f
             ^
             entire condition is false, so return first operand that validates as false,
             so, a = ''


Conclusion:

结论:

If you want JavaScript to act the same way how other programming languages work, use Boolean()function, like this:

如果您希望 JavaScript 以与其他编程语言相同的方式工作,请使用Boolean()函数,如下所示:

var a = Boolean(1 || 2 || 3);// a = true

回答by Ifeora Okechukwu

I think you have basic JavaScript methodology question here.

我认为您在这里有基本的 JavaScript 方法问题。

Now, JavaScript is a loosely typed language. As such, the way and manner in which it treats logical operations differs from that of other standard languages like Java and C++. JavaScript uses a concept known as "type coercion" to determine the value of a logical operation and always returns the value of the first truetype. For instance, take a look at the code below:

现在,JavaScript 是一种松散类型的语言。因此,它处理逻辑运算的方式和方式不同于其他标准语言,如 Java 和 C++。JavaScript 使用称为“类型强制”的概念来确定逻辑操作的值,并始终返回第一个true类型的值。例如,看看下面的代码:

var x = mystuff || document;
// after execution of the line above, x = document

This is because mystuffis an a prioriundefined entity which will always evaluate to falsewhen tested and as such, JavaScript skips this and tests the next entity for a truevalue. Since the document object is known to JavaScript, it returns a truevalue and JavaScript returns this object.

这是因为mystuff一个先验未定义的实体,它false在测试时总是会评估为,因此,JavaScript 会跳过这个并测试下一个实体的true值。由于 JavaScript 知道文档对象,它返回一个true值,JavaScript 返回这个对象。

If you wanted a boolean value returned to you, you would have to pass your logical condition statement to a function like so:

如果你想要一个布尔值返回给你,你必须将你的逻辑条件语句传递给一个函数,如下所示:

var condition1 = mystuff || document;

function returnBool(cond){
  if(typeof(cond) != 'boolean'){ //the condition type will return 'object' in this case
     return new Boolean(cond).valueOf();
  }else{ return; }
}    
// Then we test...
var condition2 = returnBool(condition1);
window.console.log(typeof(condition2)); // outputs 'boolean' 

回答by JacquesB

You should think of the short-circuit operators as conditionalsrather than logical operators.

您应该将短路运算符视为条件而不是逻辑运算符。

x || yroughly corresponds to:

x || y大致对应于:

if ( x ) { return x; } else { return y; }  

and x && yroughly corresponds to:

x && y大致对应于:

if ( x ) { return y; } else { return x; }  

Given this, the result is perfectly understandable.

鉴于此,结果是完全可以理解的。



From MDN documentation:

来自MDN 文档

Logical operators are typically used with Boolean (logical) values. When they are, they return a Boolean value. However, the && and || operators actually return the value of one of the specified operands, so if these operators are used with non-Boolean values, they will return a non-Boolean value.

逻辑运算符通常与布尔(逻辑)值一起使用。当它们是时,它们返回一个布尔值。然而,&& 和 || 运算符实际上返回指定操作数之一的值,因此如果这些运算符与非布尔值一起使用,它们将返回一个非布尔值

And here's the tablewith the returned values of all logical operators.

这里的表与所有逻辑运算符的返回值。

回答by IcyBrk

We can refer to the spec(11.11) of JS here of:

我们可以参考这里的 JS 规范(11.11):

Semantics

语义

The production LogicalANDExpression :LogicalANDExpression &&BitwiseORExpression is evaluated as follows:

产生式 LogicalANDExpression :LogicalANDExpression &&BitwiseORExpression 计算如下:

  1. Evaluate LogicalANDExpression.
  1. 评估逻辑与表达式。

2.Call GetValue(Result(1)).

2.调用GetValue(Result(1))。

3.Call ToBoolean(Result(2)).

3.Call ToBoolean(Result(2))。

4.If Result(3) is false, return Result(2).

4.如果Result(3)为false,则返回Result(2)。

5.Evaluate BitwiseORExpression.

5. 评估 BitwiseORExpression。

6.Call GetValue(Result(5)).

6.调用GetValue(Result(5))。

7.Return Result(6).

7.返回结果(6)。

see herefor the spec

请参阅此处了解规格

回答by Christophe

Compare:

相比:

var prop;
if (obj.value) {prop=obj.value;}
else prop=0;

with:

和:

var prop=obj.value||0;

Returning a truthy expression - rather than just true or false - usually makes your code shorter and still readable. This is very common for ||, not so much for &&.

返回一个真实的表达式 - 而不仅仅是 true 或 false - 通常会使您的代码更短并且仍然可读。这对于 || 来说很常见,而对于 && 来说则不然。

回答by Quentin

First, it has to be true to return, so if you are testing for truthfulness then it makes no difference

首先,返回必须是真实的,所以如果你正在测试真实性,那么它没有区别

Second, it lets you do assignments along the lines of:

其次,它允许您按照以下方式进行分配:

function bar(foo) {
    foo = foo || "default value";