这是什么 JavaScript 语法?

11

我对JavaScript很新。以下代码来自一些生产代码库。 regDefinition以JSON形式传递。但是我不太确定方法体中的语法。 特别是||[]部分。

function getCookieValue(regDefinition) {
    return (document.cookie.match(regDefiniation.regEx) || [])[regDefiniation.index] || null;
}

1
给其他人的快速提示: "[]" 表示 "new Array()",即一个空数组。 - David Refoua
5个回答

31

看起来有人很用心地让这很难读懂。

如果我理解正确,它做的事情类似于以下内容:

  • 调用match方法。
  • 它返回匹配项的数组,或者没有任何返回值(null、undefined?)。如果没有返回值,则默认为空数组。
  • 从数组中获取具有“regDefiniation.index”索引的元素。
  • 如果该项不存在(对于匹配项可能是这种情况,并且对于空的默认数组始终如此),则返回null。

7
非常正确。除了最初几分钟的个人满足感之外,用这种方式编写代码对你或最终用户没有任何好处。可读性为王。通过投票决定。而且...他本应该把 regDefiniation 拼对! - techfoobar
2
这也可能是随着时间推移而增长的代码。也许最初的编码者认为 match 总是会返回一个数组。然后代码失败了,有人通过添加 || [] 部分进行了热修复。无论原因如何,在添加一行注释甚至更好的情况下,花费 3 或 5 行代码来使其可读是没有任何羞耻感的。 - GolezTrol
2
非常感谢。我总是更喜欢可读性。但有时,有些人更喜欢把他们的名声押在“不可读性”上。 - smwikipedia
21
stuff() || default 是Javascript中的一种惯用表达式,一旦习惯了阅读它并不难理解。增加一些空格会更有帮助,但我认为将其分成ifelse语句对于大多数Javascript程序员来说过于冗长。 - Fengyang Wang
@FengyangWang 是的,但是如果将几个这样的表达式组合在一起,即使你知道语法,阅读起来也会更加困难。如果像这样两行代码 var matches = document....match(..) || []; return matches[index] || null;,它已经更易读了,同时没有if语句,只有两行代码,仍然具有相同的表达式。 - GolezTrol

25

这里有一些好的回答,但似乎没有人真正解释为什么要这样做。

(foo || [])[bar]; // or similarly (foo || {})[bar]

不仅仅是

foo[bar]

考虑正则表达式RegExp匹配失败的情况。

var foo = null, bar = 0;

如果没有任何特殊处理,你将会收到一个错误并且代码会停止运行。

foo[bar]; // TypeError: Cannot read property '0' of null

然而带括号的或运算符版本将不同。

(foo || [])[bar]; // undefined (note, no error)

这是因为(null || [])的结果是[],所以现在您可以安全地尝试读取它的属性。


2
我认为每个答案都提到了 || [] 是为了防止 match 没有返回任何内容。特别是 @Wyzard 的(被低估的)答案非常清楚地解释了这一点。但我们两个都没有详细说明会出现什么样的错误,所以对此表示赞赏。 - GolezTrol

7
document.cookie 是一个包含当前页面的 cookie 的字符串。调用 document.cookie.match(regDefiniation.regEx) 函数使用正则表达式搜索这个字符串,以获取与之匹配的子字符串列表。
如果在 cookie 字符串中没有任何东西与正则表达式匹配,match 调用将返回 null,所以 || [] 用于将该 null 替换为一个空数组。这确保了表达式 (document.cookie.match(regDefiniation.regEx) || []) 总是返回一个数组。 [regDefiniation.index] 只是从该数组中检索一个元素。但是,如果请求的索引在数组中不存在(例如,如果数组为空因为正则表达式在 cookie 字符串中没有找到任何内容),结果将是 undefined,所以 || null 将在这种情况下将结果更改为 null

6

因此,要理解这个例子,让我们深入了解一下。

var myValue = someValue || otherValue

如果someValue可以转换为true,那么myValue将包含someValue,否则它将包含otherValue。
// Values that evaluate to false:
false
"" // An empty string.
NaN // JavaScript's "not-a-number" variable.
null
undefined // Be careful -- undefined can be redefined!
0 // The number zero.

任何其他情况都会返回 true。
因此,为了理解你的代码,让我们来分析一下。
var myCookie = document.cookie.match(regDefiniation.regEx) || []

如果document.cookie.match(regDefiniation.regEx)返回true,则返回它,否则返回空数组。对于其它部分也同样如此。了解JavaScript中的逻辑运算符的更多信息,请访问以下链接。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators


@AshishRajput 我认为它更像是一个空数组而不仅仅是一个对象。在JavaScript中,空对象被定义为{} - The amateur programmer

3
这里是逐步操作: document.cookie 返回一个字符串,然后应用 match 方法(内置)。如果参数在 regDefiniation.regEx 中找到,则执行此操作,否则返回 [](即数组)。 接下来,将上一步返回的任何内容与 [regDefiniation.index] 进行索引。
如果所有上述步骤都失败,则返回 null。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接