给出这段JavaScript代码…

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

有人能给我解释一下这个技巧叫什么吗(我最好的猜测是在这个问题的标题中!)?它究竟是如何/为什么工作的?

我的理解是,变量f将被赋给第一个具有非null或未定义值的变量的最近值(从左到右),但我没有设法找到关于这种技术的很多参考资料,并且已经看到它被大量使用。

另外,这种技术是JavaScript特有的吗?我知道在PHP中做类似的事情会导致f有一个真正的布尔值,而不是d本身的值。


当前回答

这个问题已经得到了几个很好的答案。

总之,这种技术利用了语言编译方式的一个特性。也就是说,JavaScript“短路”了布尔运算符的求值,并将返回与第一个非假变量值或最后一个变量包含的任何值相关联的值。参见Anurag对这些值的解释,这些值将被计算为假。

出于几个原因,使用这种技术并不是一种好的实践;然而。

Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value. Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future. Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator: () ? value 1: Value 2.

使用三元操作符确实需要更多的输入,但它可以清楚地区分要计算的布尔表达式和要赋值的值。此外,它还可以被链接,因此可以重新创建上面执行的默认赋值类型。

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4

其他回答

这意味着如果设置了x,则z的值将为x,否则如果设置了y,则其值将设置为z的值。

这和

if(x)
  z = x;
else
  z = y;

这是可能的,因为JavaScript中的逻辑运算符并不返回布尔值,而是返回完成操作所需的最后一个元素的值(在OR句中,它将是第一个非假值,在AND句中,它将是最后一个)。如果操作失败,则返回false。

返回输出的第一个真值。

如果全部为假,则返回最后一个假值。

例子:-

  null || undefined || false || 0 || 'apple'  // Return apple

说明请参见短路评估。这是实现这些运算符的常用方式;它并不是JavaScript独有的。

它将计算X,如果X不为空字符串或0(逻辑错误),那么它将把它赋值给z。如果X为空字符串或0(逻辑错误),那么它将把y赋值给z。

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

将输出'bob';

它将新变量(z)设置为x的值(如果它是“真值”(非零,有效的对象/数组/函数/无论它是什么)或y。这是在x不存在的情况下提供默认值的一种相对常见的方式。

例如,如果你有一个接受可选回调参数的函数,你可以提供一个默认的不做任何事情的回调:

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}