为什么这些逻辑运算符返回一个对象而不是布尔值?
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
var _ = obj && obj._;
我想了解为什么它返回obj.fn()
(如果已定义)ORobj._
结果而不是布尔结果。
为什么这些逻辑运算符返回一个对象而不是布尔值?
var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
var _ = obj && obj._;
我想了解为什么它返回obj.fn()
(如果已定义)ORobj._
结果而不是布尔结果。
在 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中false
,0
, -0
, ""
, null
,undefined
和NaN
都算作 false。document.all
为了讨论,我当然在这里引用逻辑值。当然,文字字符串"false"
与 value 不同false
,因此为 true。
用最简单的话来说:
运算符返回第||
一个真值,如果没有一个真值,则返回最后一个值(这是一个假值)。
运算符返回第&&
一个假值,如果没有假值,则返回最后一个值(这是一个真值)。
真的就是这么简单。在您的控制台中进行实验以亲自查看。
console.log("" && "Dog"); // ""
console.log("Cat" && "Dog"); // "Dog"
console.log("" || "Dog"); // "Dog"
console.log("Cat" || "Dog"); // "Cat"
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._
在大多数编程语言中,&&
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
您应该将短路运算符视为条件而不是逻辑运算符。
x || y
大致对应:
if ( x ) { return x; } else { return y; }
大致x && y
对应于:
if ( x ) { return y; } else { return x; }
鉴于此,结果是完全可以理解的。
来自MDN 文档:
逻辑运算符通常与布尔(逻辑)值一起使用。当它们存在时,它们返回一个布尔值。但是,&& 和 || 运算符实际上返回指定操作数之一的值,因此如果这些运算符与非布尔值一起使用,它们将返回一个非布尔值。
这是所有逻辑运算符的返回值的表。
我认为您在这里有基本的 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'
我们可以参考这里的 JS 规范(11.11):
语义
产生式 LogicalANDExpression :LogicalANDExpression &&BitwiseORExpression 的评估如下:
2.调用GetValue(Result(1))。
3.调用ToBoolean(结果(2))。
4.如果Result(3)为假,返回Result(2)。
5.评估 BitwiseORExpression。
6.调用GetValue(Result(5))。
7.返回结果(6)。
请参阅此处了解规格
首先,它必须是真实的,所以如果你正在测试真实性,那么它没有任何区别
其次,它允许您按照以下方式进行分配:
function bar(foo) {
foo = foo || "default value";
比较:
var prop;
if (obj.value) {prop=obj.value;}
else prop=0;
和:
var prop=obj.value||0;
返回一个真实的表达式——而不仅仅是真或假——通常会使你的代码更短并且仍然可读。这对于 || 很常见,而对于 && 则不常见。