52

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

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

var _ = obj && obj._;

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

4

9 回答 9

74

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

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

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

并且&&做同样的事情,除了它停止评估第一个参数是否为假。

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

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

在 JS中false0, -0, "", null,undefinedNaN算作 falsedocument.all

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

于 2011-12-20T02:02:12.773 回答
69

用最简单的话来说:

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

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

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

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

于 2015-08-22T17:30:31.267 回答
18
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 

将返回布尔值。

更新

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

它是一个赋值true或不赋值的表达式false。相反,它分配计算值。

让我们看看这个表达式。

一个示例表达式:

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._
于 2011-03-24T10:53:58.367 回答
7

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


或运算符:

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

示例 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 = ''

与运算符:

它返回验证为 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
于 2017-02-13T10:25:54.607 回答
5

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

x || y大致对应:

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

大致x && y对应于:

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

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


来自MDN 文档

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

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

于 2019-11-06T10:55:34.283 回答
3

我认为您在这里有基本的 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' 
于 2013-04-26T20:40:24.290 回答
2

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

语义

产生式 LogicalANDExpression :LogicalANDExpression &&BitwiseORExpression 的评估如下:

  1. 计算逻辑与表达式。

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

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

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

5.评估 BitwiseORExpression。

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

7.返回结果(6)。

请参阅此处了解规格

于 2013-01-11T18:45:38.133 回答
1

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

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

function bar(foo) {
    foo = foo || "default value";
于 2011-03-24T10:52:01.377 回答
1

比较:

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

和:

var prop=obj.value||0;

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

于 2013-01-11T19:07:40.503 回答