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が少なくとも大まかにtrue(、、1
など"string"
)であることを意味!!x
し、少なくとも大まかにfalse(、、など)であることを意味します。x
0
""
この回答は、さらにいくつかのオプションを提供します。ただし、これらはすべてネイティブにフォールバックすることを目的としているためindexOf
、スクリプトランドでコーディングできるものよりもほぼ確実に高速になります。