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

发布于 2024-10-26 06:58:03 字数 210 浏览 2 评论 0原文

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

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

var _ = obj && obj._;

我想了解为什么它返回 obj.fn() 的结果(如果已定义)或 obj._ ,但不返回布尔结果。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

不寐倦长更 2024-11-02 06:58:03

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

在表达式 X || 中YX 首先被求值,并解释为布尔值。如果此布尔值为“true”,则返回它。并且 Y 不会被评估。 (因为 Y 为 true 或 Y 为 false 并不重要,X || Y 已完全确定。)短路部分。

如果这个布尔值为“false”,那么我们仍然不知道 X || 是否成立。在我们计算 Y 并将其解释为布尔值之前,Y 要么是 true 要么是 false。那么Y就会被返回。

&& 的作用相同,只是如果第一个参数为 false 则停止计算。

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

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

在 JS 中 false0-0""null、<代码>未定义,<代码>NaN和<代码>document.all全部算作 false

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

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

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

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

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.

In JS false, 0, -0, "", null, undefined, NaN and document.all all count as 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.

伴我老 2024-11-02 06:58:03

用最简单的术语来说:

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

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

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

console.log("" && "Dog");    // ""
console.log("Cat" && "Dog"); // "Dog"
console.log("" || "Dog");    // "Dog"
console.log("Cat" || "Dog"); // "Cat"

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).

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.

console.log("" && "Dog");    // ""
console.log("Cat" && "Dog"); // "Dog"
console.log("" || "Dog");    // "Dog"
console.log("Cat" || "Dog"); // "Cat"

她比我温柔 2024-11-02 06:58:03
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 

将返回布尔值。

更新

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

它是一个分配truefalse 值的表达式。相反,它分配计算值。

我们来看看这个表达式。

表达式示例:

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;

您的表达式:

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

另一个表达式:

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

另一个表达式:

var _ = obj && obj._;

// _ = obj._
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 not assign true or false value. Rather it assigns the calculated value.

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._
彡翼 2024-11-02 06:58:03

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


OR 运算符:

它返回验证为 true 的第一个操作数的值(如果有),否则返回最后一个操作数的值< /strong>(即使它验证为 false)

示例 1:

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

示例 2:

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

AND 运算符:

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

示例 1:

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

示例 2:

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

结论

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

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

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


OR Operator:

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

Example 1:

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

Example 2:

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

AND Operator:

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

Example 1:

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

Example 2:

var a = 2 && '' && 3 && null;
        ^    ^     ^    ^
        t    f     t    f
             ^
             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:

var a = Boolean(1 || 2 || 3);// a = true
满栀 2024-11-02 06:58:03

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

<代码>x || y 大致对应于:

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

x && y 大致对应于:

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

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


来自 MDN 文档

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

并且 下表包含所有逻辑运算符的返回值。

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

x || y roughly corresponds to:

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

and x && y roughly corresponds to:

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

Given this, the result is perfectly understandable.


From MDN documentation:

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 table with the returned values of all logical operators.

魂归处 2024-11-02 06:58:03

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

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

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

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

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

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' 

I think you have basic JavaScript methodology question here.

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 true type. For instance, take a look at the code below:

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

This is because mystuff is an a priori undefined entity which will always evaluate to false when tested and as such, JavaScript skips this and tests the next entity for a true value. Since the document object is known to JavaScript, it returns a true value and JavaScript returns this object.

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' 
森末i 2024-11-02 06:58:03

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

Semantics

产生式 LogicalANDExpression :LogicalANDExpression &&BitwiseOREExpression 的计算如下:

  1. Evaluate LogicalANDExpression。

2.调用GetValue(结果(1))。

3.调用ToBoolean(结果(2))。

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

5.评估 BitwiseOREExpression。

6.调用GetValue(结果(5))。

7.返回结果(6)。

请参阅此处了解规范

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

Semantics

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

  1. Evaluate LogicalANDExpression.

2.Call GetValue(Result(1)).

3.Call ToBoolean(Result(2)).

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

5.Evaluate BitwiseORExpression.

6.Call GetValue(Result(5)).

7.Return Result(6).

see here for the spec

似梦非梦 2024-11-02 06:58:03

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

其次,它允许你按照以下方式进行作业:

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

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";
衣神在巴黎 2024-11-02 06:58:03

比较:

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

与:

var prop=obj.value||0;

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

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 &&.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文