我知道
(M[key] || (M[key] = [])).push(elem);
是解决常见问题的常用方法
"如果数组存在,并且不存在,初始化数组,然后推送元素"
但是语法是如何分解的呢?以下是我的看法:
||
的存在意味着该运算符左侧和右侧的任何内容都被解释为布尔值。因此,M[key]
和(M[key] = [])
要么是布尔值,要么是被强制转换为布尔值的语句。在任何一种情况下,我都看不出如何将push
加在(M[key] || (M[key] = [])
的值上。这到底是怎么回事?
这确实是JavaScript中非常常见的模式。
您需要向与键关联的列表中添加一个元素,如果不存在,则创建一个新列表。
要获得与密钥相关联的列表,代码为:
M[key]
但如果不存在CCD_ 7,则返回CCD_。
Javascript ||
(逻辑或)运算符有一个非常有用的语义:如果左侧为true,则返回它,否则计算并返回右侧。表达式:
M[key] || (M[key] = [])
因此,如果存在,则返回与M[key]
相关联的列表,否则对部分(M[key] = [])
进行评估。这是因为数组(即使为空)在JavaScript中为true,而undefined
为false。
赋值运算符=
(这是JavaScript中的一个普通运算符,可以在表达式中间使用)执行赋值,然后返回刚刚赋值的值。
因此,整个过程只是返回与密钥相关联的列表,或者如果密钥在M
中未知,则创建一个新的空列表。
将元素推到数组中是<array>.push(x)
,点左侧的部分可以是任何表达式。
(M[key] || (M[key] = [])).push(x);
因此将CCD_ 15添加到由左侧表达式返回的列表中。
"扩展版本看起来是这样的:
if (!M[key]) {
M[key] = [];
}
M[key].push(x);
请注意,在JavaScript中使用对象作为字典需要注意,因为继承了成员。例如,对于M = {}
和key = "constructor"
,该代码将失败。
M[key]
有一个值(一个真实的值),那就是所使用的值,我们就完成了。否则第二部分就完成了。
写出来的长表格,你可能有:
if (M[key]) M[key].push(elem);
else {
M[key] = [];
M[key].push(elem);
}
所以你可以理解为什么这个较短的成语会发展起来。
使用您的操作顺序!跟在括号后面。
(M[key] || (M[key] = [])).push(elem);
把它分解。(M[key] || (M[key] = []))
||
是OR运算符。因此,如果M[key]
存在,则push
为其添加新元素。如果不存在,则创建数组并添加它。
它被认为是一种真实的比较。(true或else)
好的,这里发生了很多事情。
首先介绍数组在javascript中的工作方式。您可以使用array_NAME[KEY_VALUE]访问或分配数组元素。
因此,如果对象存在,M[Key]将返回该对象。
基于此代码,M是数组的数组。因此,当M[Key]求值时,它将返回一个数组或null。
当表达式a||b在javascript中求值时,它会短路,也会从左到右求值——也就是说,如果a为true,则从不求值b——如果a为false,则求值b。(这在许多类C语言中很常见。)
由于M[Key]将在对象存在的情况下返回对象,因此不会对||之后的部分求值,并且该键处的数组用于推送新的elem。
如果在M[Key]处不存在任何东西,则对b部分进行求值,并且在这种情况下,b部分首先将空数组([]
)分配给M[Key]处的位置(正如我们在M[Key]之前所指出的,也可以用于赋值)。然后使用这个新的空数组(因为它是对()
内的表达式求值的结果)来推送新的elem。
https://en.wikipedia.org/wiki/Short-circuit_evaluation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
我是这样理解的:javascript中未定义为boolean是false。
(M[key] || (M[key] = [])).push(elem);
按以下方式执行:若M[key]不是未定义的-false,则表达式的结果为M[key]。
如果M[key]为undefined-false,则执行boolean ||-OR运算符的第二部分,并且M[key]获得空数组作为值。表达式的结果是M[key],但现在它有一个空数组作为值。
然后我们将新的值推入M[key]数组:M[key].prush(elem);
我认为这是有用的javascript运算符和truthy-falsy