var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
那是一段可怕的代码,你应该远离它。这里完全不需要位运算符,并且 c 和 d 作为参数根本毫无意义(正如 Raymond Chen 指出的那样,代码作者可能这样做是为了节省声明本地变量的空间--但问题在于如果将 true 传递给 d,代码就会突然崩溃,而额外的参数破坏了扫视声明时提供的任何理解)。
我会解释代码,但首先,以下是更好的选项:
function inArray(arr, obj) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) {
return true;
}
}
return false;
}
注意,这取决于数组是实际的数组。你可以使用类似
for (k in arr)
的循环来将其推广至所有对象。
无论如何,接下来进行解释:
for (c in b) d |= b[c] === a
这意味着对于 b 中的每个键(存储在 c 中),我们将检查
b [c] === a
。换句话说,我们正在对数组进行线性扫描,并检查每个元素是否与
a
相等。
d | = val
是按位或运算符。
val
中高位的位将在
d
中设置为高位。这在比JS更暴露位的语言中更容易说明,但可以用简单的例子来说明:
10011011
01000001
11011011
它只是将每个位与另一个值的相同位置位进行OR运算。
滥用它的原因在于它使代码变得混乱,并且依赖于奇怪的隐式转换。
x === y
返回一个布尔值。在按位表达式中使用布尔值几乎没有意义。但实际上,布尔值被转换为非零值(可能是1
)。
同样地,undefined
是d
的值。这意味着d
将被转换为进行位运算的数字0。
0 | 0 = 0
,但0 | 1 = 1
。所以基本上它是一种精美的形式:
for (c in b) d = (d || (b[c] === a))
关于
!!x
的用法是将某个值强制转换为布尔型。而
!x
会将x隐式地转换为布尔型,再对其取反。额外的
!
符号再次取反结果。因此,
!!x
被解读为true,意味着x至少是宽松的真(
1
,
"string"
等),而
!!x
则暗示x至少是宽松的假(
0
,
""
等)。
这个答案提供了几个选项,但请注意,所有这些选项都是为了回退到本地的
indexOf
函数,该函数几乎肯定比我们在代码中编写的任何内容都要快。
for...in
?厉害!?在我看来,这段代码令人十分反感。 - Elias Van Ootegem