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は、ブールに何かをキャストするために使用されます。 !xxを取り、暗黙的にブール値にキャストしてから無効にします。その後、余分な!ものはそれを再び否定します。したがって、暗黙的にブール値にキャストしている可能性があります(!!xtrueであるということは、xが少なくとも大まかにtrue(、、1など"string")であることを意味!!xし、少なくとも大まかにfalse(、、など)であることを意味します。x0""
この回答は、さらにいくつかのオプションを提供します。ただし、これらはすべてネイティブにフォールバックすることを目的としているためindexOf、スクリプトランドでコーディングできるものよりもほぼ確実に高速になります。