Javascript表达式'a = a ||是什么 function(){...}'是什么意思?

Van*_*goe 16 javascript construct

我不确定这个结构意味着什么,但我已经看过几次了.下面的示例来自另一个Stack Overflow问题.我不确定如何解释最初的"或"构造本身:

Object.keys = Object.keys || (function () {
  var hasOwnProperty = Object.prototype.hasOwnProperty,
      hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
      DontEnums = [ 
          'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
          'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
      ],
      DontEnumsLength = DontEnums.length;
  //etc...
});
Run Code Online (Sandbox Code Playgroud)

Pet*_*son 19

a = a || function(){...}是一个在Javascript中非常常见的习语.它依赖于两个概念,虽然不是Javascript独有的,但您可能还不熟悉.

1. 操作员短路

运算符短路[wikipedia]是为避免不必要的评估而发明的编译器优化.

为了证明这一点,让我们假设我们想确定一个人是否是青少年:即一个人的年龄是否介于13至19岁之间.

var isTeenager = person.age >= 13 && person.age <= 19;
Run Code Online (Sandbox Code Playgroud)

现在,让我们假设代码执行并且结果是该人小于13岁.将评估第一个条件并返回false.由于程序现在知道&&操作员的左侧是false,并且由于&&需要两侧true进行评估true,因此它知道评估右侧是没有意义的.

换句话说,该节目已经知道该人的年龄不超过13岁,已经知道他不是青少年,并且不会在乎他是否小于19岁.

同样的原则适用于||运营商.假设我们想知道一个人是否可以免费乘坐公共汽车:也就是说,如果这个人已经超过70岁或者是残障人士.

var canRideFree = person.age >= 70 || isHandicapped(person);
Run Code Online (Sandbox Code Playgroud)

如果这个人超过70岁,该计划已经知道他可以免费乘坐.此时,程序不关心他是否有残障,因此不评估对该isHandicapped功能的调用.另一方面,如果这个人年龄小于70岁,那么canRideFree将被设定为任何isHandicapped回报.

2. Truthy和falsy值

Truthy和falsy值[一些随机人的博客]是对象的布尔值.在Javascript中,每个对象都将评估为"truthy"或"falsy"值.

如果表达式的值是以下任何一个,则表达式为"falsy":

false, null, undefined, 0, "", NaN
Run Code Online (Sandbox Code Playgroud)

其他一切都是真实的.

人们利用null或undefined变量求值的事实false.这意味着您可以非常轻松地检查变量是否存在:

if (a) { /* a exists and is not a falsy value */ }
Run Code Online (Sandbox Code Playgroud)

结合我们所知道的

||运营商短路,并返回其计算上次表达式的值.这一原则在这一单一陈述中与真实性相结合:

Object.keys = Object.keys || function() {...}
Run Code Online (Sandbox Code Playgroud)

如果Object.keys是真实的,它将被评估并分配给自己.否则,Object.keys将分配给该功能.这是Javascript中非常常见的习惯用法,用于检查某个值是否已经存在并将其分配给其他内容(如果不存在).

其他一些语言,如C#,没有真实性,有一个具有类似目的的空合并运算符[MSDN].

object Value = PossiblyNullValue ?? ValueIfNull;
Run Code Online (Sandbox Code Playgroud)

在此代码中,Value将被分配给PossiblyNullValue,除非它为null,在这种情况下它将被分配给ValueIfNull.

tl;博士[维基百科]

如果您没有阅读我上面所说的任何内容,您需要知道的是,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);
}
Run Code Online (Sandbox Code Playgroud)

  • 从现在开始,我完全窃取你的上标括号中的链接引用,不敢相信我已经没有在这里看到更多. (4认同)

Chr*_*nte 2

据我所知,Object.keys如果该函数尚未定义(或者为 false),则该代码会尝试定义该函数。左边的函数||将成为函数Object.keys

我之所以说“据我所知”是因为您还没有发布整个代码片段。||请注意,读取后的代码(function(){不仅仅是function(){. 有可能作者已经将函数设置为自调用。

如果在函数定义之后看到})(),则函数的返回值存储在 中Object.keys。如果没有,则函数本身存储在那里。