25

私はこのブログ投稿を読んでいました。

!!~ 

私はこれが何をするのか分かりませんか?最初はエラーが発生すると思いましたが、以下のコードは実行されます。

var _sessions = [
    "_SID_1",
    "_SID_2",
    "_SID_3",
    "_SID_4"
];

if(!!~_sessions.indexOf("_SID_5")) {
    console.log('found');
} else {
    console.log('!found');
}

出力:

node test.js 
!found
4

3 に答える 3

28

~ビット単位のnot演算子です。オペランドのビットを反転します。!論理否定演算子です。ビット単位のnot演算子は0、に適用されると戻ります-1。これはindexOf、値が配列に見つからない場合に返されるものです。0に評価されるのでfalse、二重に否定すると、単純にfalse(数値ではなくブール値)が返されます。

var index = _sessions.indexOf("_SID_5");
console.log(~index); // 0
console.log(!~index); // true
console.log(!!~index); //false

ビット単位のnot演算子は、によって返される他の可能な値に対して0未満の値を返しindexOfます。他の値はと評価されるのでtrue、これは、要素が配列に存在するかどうかを明示的に比較するのではなく、(一種の...両方とも同じ文字数です!)簡単な方法です-1

if (_sessions.indexOf("_SID_5") > -1) {
    // This would work the same way
}

アップデート

これのパフォーマンスに関しては、(少なくともChromeでは)より一般的な比較よりもわずかに遅いように見えます(-1それ自体はとの比較よりもわずかに遅いです0)。

これがテストケースで、結果は次のとおりです。

ここに画像の説明を入力してください

アップデート2

実際、あなたの質問のコードは短くすることができます。それは作者がやろうとしていたことかもしれません。は常に以下の結果になる!!ため、を削除するだけで済みます(そして、評価される唯一の値です)。~00false

if (~_sessions.indexOf("_SID_5")) {
    // This works too
}

ただし、少し異なる状況では、!演算子を追加するのが理にかなっている場合があります。ビット演算子の結果を変数に格納する場合、それは数値になります。論理否定演算子を適用すると、ブール値が得られます(そして、もう一度適用すると、正しいブール値が得られます)。何らかの理由で数値よりもブール値が必要な場合は、もう少し意味があります(ただし、またはとの通常の比較を使用することもできます-10

var inArray = !!~_sessions.indexOf("_SID_5");
console.log(typeof inArray); // boolean
于 2012-11-28T11:13:13.547 に答える
7

ドナルド・クヌース:「[...]時期尚早の最適化はすべての悪の根源です」

読みやすくするために:を使用してください

.indexOf !== -1
于 2012-11-28T11:26:06.097 に答える
5

これはそれをよく説明しています:

Javascriptのチルダ演算子

2つのNOT演算子を一緒に混合すると、いくつかの興味深い結果が得られます。

!〜(-2)= false

!〜(-1)= true

!〜(0)= false

!〜(1)= false

!〜(2)= false

したがって、これは値が-1に等しいかどうかをチェックするだけであり、一致するものが見つからない場合、indexOfは-1を返します。

于 2012-11-28T11:13:02.467 に答える