给出这段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本身的值。


当前回答

它没有任何魔力。布尔表达式如a || b || c || d被延迟计算。Interpeter寻找a的值,它是未定义的,所以它是假的,所以它继续前进,然后它看到b是空的,它仍然给出假的结果,所以它继续前进,然后它看到c -同样的故事。最后它看到d,然后说,嗯,它不是空的,所以我得到了我的结果,然后它把它赋值给final变量。

这个技巧适用于所有对布尔表达式进行惰性短路计算的动态语言。在静态语言中它不会被编译(类型错误)。在渴望计算布尔表达式的语言中,它将返回逻辑值(即在本例中为true)。

其他回答

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

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

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

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

总之,这种技术利用了语言编译方式的一个特性。也就是说,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

它没有任何魔力。布尔表达式如a || b || c || d被延迟计算。Interpeter寻找a的值,它是未定义的,所以它是假的,所以它继续前进,然后它看到b是空的,它仍然给出假的结果,所以它继续前进,然后它看到c -同样的故事。最后它看到d,然后说,嗯,它不是空的,所以我得到了我的结果,然后它把它赋值给final变量。

这个技巧适用于所有对布尔表达式进行惰性短路计算的动态语言。在静态语言中它不会被编译(类型错误)。在渴望计算布尔表达式的语言中,它将返回逻辑值(即在本例中为true)。

Javascript变量没有类型,所以f可以被赋值为整数值,即使它是通过布尔运算符赋值的。

F被赋给不等于false的最接近的值。0, false, null, undefined,都被传递:

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'

根据Bill Higgins的博客文章;Javascript逻辑或赋值习惯(2007年2月),这个行为在v1.2(至少)是正确的。

他还提出了另一种用法(引用): “跨浏览器差异的轻量级规范化”

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;