a = a || function(){...}
是 Javascript 中非常常见的一个成语。它依赖于两个概念,虽然这不是 Javascript 独有的,但您可能还不熟悉。
1.操作员短路
运算符短路[wikipedia]是一种编译器优化,旨在防止不必要的评估。
为了证明这一点,让我们假设我们要确定一个人是否是青少年:即一个人的年龄是否在 13 到 19 岁之间。
var isTeenager = person.age >= 13 && person.age <= 19;
现在,让我们假设代码执行并且结果是这个人小于 13 岁。将评估第一个条件并将返回 false。由于程序现在知道运算符的左侧&&
是false
,并且由于&&
需要两边都是true
才能计算到true
,所以它知道计算右侧是没有意义的。
也就是说,程序看到这个人的年龄不超过13岁,就已经知道他不是青少年,不管他是否低于19岁。
同样的原则也适用于||
运营商。假设我们想知道一个人是否可以免费乘坐公共汽车:也就是说,这个人是否超过 70 岁或是否有残障。
var canRideFree = person.age >= 70 || isHandicapped(person);
如果这个人超过 70 岁,程序已经知道他可以免费骑行。此时,程序不关心他是否有障碍,因此不会评估对isHandicapped
函数的调用。另一方面,如果这个人小于 70 岁,那么canRideFree
将被设置为任何isHandicapped
返回值。
2.真值和假值
真值和假值[一些随机人的博客]是对象的布尔评估。在 Javascript 中,每个对象都将评估为“真实”或“虚假”值。
如果表达式的值是以下任何一种,则表达式是“假的”:
false, null, undefined, 0, "", NaN
其他一切都是真实的。
人们利用 null 或未定义变量的计算结果为false
. 这意味着您可以很容易地检查变量是否存在:
if (a) { /* a exists and is not a falsy value */ }
结合我们所知道的
||
运算符短路并返回它计算的最后一个表达式的值。在这个单一的陈述中,这一原则与真实性相结合:
Object.keys = Object.keys || function() {...}
如果Object.keys
是真的,它将被评估并分配给它自己。否则,Object.keys
将分配给该功能。这是 Javascript 中一个非常常见的习惯用法,用于检查一个值是否已经存在,如果不存在则将其分配给其他东西。
其他一些没有真实性的语言,例如 C#,有一个具有类似目的的空合并运算符[MSDN] 。
object Value = PossiblyNullValue ?? ValueIfNull;
在此代码中,Value
将分配给PossiblyNullValue
,除非它为空,在这种情况下,它将分配给ValueIfNull
。
如果您没有费心阅读我上面所说的任何内容,那么您只需要知道a = a || function() {...}
基本上就是执行此代码的功能:
if (exists(Object.keys)) {
Object.keys = Object.keys;
} else {
Object.keys = function() {...};
}
function exists(obj) {
return typeof obj !== "undefined" &&
obj !== null &&
obj !== false &&
obj !== 0 &&
obj !== "" &&
!isNaN(obj);
}