var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
那是一些糟糕的代码,你应该远离它。位运算符在这里完全没有必要,c而且d作为参数根本没有意义(正如 Raymond Chen 指出的那样,代码的作者可能是为了声明局部变量的安全空间而这样做的——但问题是 iftrue被传入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
它只是将每个单独的位与另一个值中的相同位置位进行或运算。
它在这里被滥用的原因是它使代码复杂化并且它依赖于奇怪的隐式强制转换。
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为真意味着 x至少是松散的真(1,"string"等),并!!x暗示至少x是松散的假(,等)。0""
这个答案提供了更多选择。请注意,尽管所有这些都是为了回退到本机indexOf,这几乎肯定会比我们在脚本领域中编写的任何代码都要快。