JavaScript最有效的功能是在数组中查找项目?并解释这个棘手的代码

Om *_*kar 4 javascript recursion

什么是在数组中查找项目的最有效方法,这是Web开发人员的逻辑和理解?

我遇到了这段代码:

var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};
Run Code Online (Sandbox Code Playgroud)

它工作正常.有人可以解释一下代码吗?
我也遇到了一个完全相同的问题,可能会使我的问题重复.但我真正的问题在于解释上面的代码以及为什么使用了按位运算符.
此外,是否有一种方法可以没有任何for循环或迭代来获取数组中项目的索引?

Cor*_*bin 5

var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};
Run Code Online (Sandbox Code Playgroud)

这是一些可怕的代码,你应该逃避它.位运算符是完全没有必要在这里,并cd被参数是没有意义的(如雷蒙陈德铭指出,该代码的作者可能它确实给声明局部变量的安全空间-问题是,虽然如果true是通过在d代码突然被打破了,额外的参数破坏了对声明的瞥见所带来的任何理解感.

我将解释代码,但首先,这是一个更好的选择:

function inArray(arr, obj) {
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] === obj) {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这取决于数组是实际数组.您可以使用for (k in arr)类型循环将其概括为所有对象.


无论如何,关于解释:

for (c in b) d |= b[c] === a;
Run Code Online (Sandbox Code Playgroud)

这意味着对于b中的每个键(存储在其中c),我们将检查是否b[c] === a.换句话说,我们正在对数组进行线性扫描并检查每个元素a.

d |= val是一个按位或.高位val将设置为高位d.在比JS更暴露位的语言中,这更容易说明,但只是简单说明:

10011011
01000001
--------
11011011
Run Code Online (Sandbox Code Playgroud)

它只是将每个单独的位与另一个值中的相同位置位进行"或"运算.

它在这里被滥用的原因是它使代码卷积,它依赖于奇怪的隐式转换.

x === y返回一个布尔值.在按位表达式中使用的布尔值没有多大意义.然而,正在发生的是布尔值被转换为非零值(可能1).

同样,将undefined是什么d.这意味着d将被转换0为按位的东西.

0 | 0 = 0但是0 | 1 = 1.所以基本上它是一个美化:

for (c in b) d = (d || (b[c] === a));
Run Code Online (Sandbox Code Playgroud)

至于!!x那只是用于向布尔施放东西. !x将x,隐含地将其强制转换为bool然后否定它.额外的!将再次否定这一点.因此,很可能隐含强制转换为布尔(!!x是真正意味着x是至少松散真(1,"string",等),并!!x暗示x至少松散假(0,"",等).


这个答案提供了更多选择.请注意,虽然所有这些都是为了回归到本机indexOf,几乎肯定会比我们可以在脚本中编码的任何东西更快.