web-dev-qa-db-ja.com

式の前にあるチルダは何をしますか?

var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'

私は答えでそれを見ました、そして、私はそれを見たことがありません。

どういう意味ですか?

175
wwaawaw

~は、オペランドのすべてのビットを反転する ビットごとの演算子 です。

たとえば、数値が1の場合、 IEEE 754 float (JavaScriptが数値を処理する方法)のバイナリ表現は...

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

したがって、~は、そのオペランドを32ビット整数に変換します(JavaScriptのビット演算子はそれを行います)...

0000 0000 0000 0000 0000 0000 0000 0001

負の数の場合、2の補数で格納されます。すべてのビットを反転し、1を追加します。

...そしてすべてのビットを反転します...

1111 1111 1111 1111 1111 1111 1111 1110

それで、それの使用は何ですか?いつそれを使うでしょうか?

かなりの用途があります。低レベルのものを書いているなら、それは便利です。アプリケーションのプロファイルを作成し、ボトルネックを見つけた場合、ビット単位のトリックを使用することでパフォーマンスを向上させることができます(1つのpossibleツールをより大きなバッグに入れて)。

また、indexOf()foundを返すことは(一般的に)不明確なtrickですintotruthynot foundとしてfalsy)そして、人々はしばしば数値を32ビットに切り捨てるという副作用のためにそれを使用します(そして、正数のMath.floor()と事実上同じである、それを2倍して小数点以下を切り捨てます)。

unclearと言うのは、それが何に使われているのかがすぐにはわからないからです。一般的に、コードを読んでいる他の人と明確に通信できるようにしたいでしょう。 ~を使用することはかっこいいかもしれませんが、一般的にはあまりにも賢明です。 :)

また、JavaScriptに Array.prototype.includes() および String.prototype.includes() があるため、あまり重要ではありません。これらはブール値を返します。ターゲットプラットフォームでサポートされている場合は、文字列または配列内の値の存在をテストするためにこれを選択する必要があります。

248
alex

indexOf()式の前にそれを使用すると、直接返される数値インデックスの代わりに、事実上/偽の結果が得られます。

戻り値が-1の場合、~-1は1ビットすべての文字列であるため、0-1です。ゼロ以上の値は、ゼロ以外の結果になります。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example、

if (~someString.indexOf(something)) {
}

「something」が「someString」にあるときにifコードが実行されます。 .indexOf()をブール値として直接使用しようとすると、ゼロが返されることがあるため(「何か」が文字列の先頭にある場合)、動作しません。

もちろん、これも機能します:

if (someString.indexOf(something) >= 0) {
}

そして、それはかなり神秘的ではありません。

時々これも表示されます:

var i = ~~something;

~演算子をそのように2回使用すると、文字列を32ビット整数に簡単に変換できます。最初の~が変換を行い、2番目の~がビットを反転させます。もちろん、数値に変換できないものに演算子を適用すると、結果としてNaNが返されます。 (編集 —実際に最初に適用されるのは2番目の~ですが、アイデアは得られます。)

98
Pointy

~ビットごとのNOT演算子~x-(x+1)とほぼ同じです。わかりやすいです。そう:

~2;    // -(2+1) ==> -3

-(x+1)を検討してください。 -1は、その操作を実行して0を生成できます。

言い換えると、~は、0入力値に対してのみ、ある範囲の数値で使用すると、偽の(-1からfalseへの強制)値を生成します。他の真実の価値。

知っているように、-1は一般的にセンチネル値と呼ばれます。 success>= 0値と-1値を返す多くの関数に使用されますC言語のfailure。 JavaScriptの indexOf() の戻り値と同じルール。

この方法で別の文字列の部分文字列の有無を確認することは一般的です

var a = "Hello Baby";

if (a.indexOf("Ba") >= 0) {
    // found it
}
if (a.indexOf("Ba") != -1) { 
    // found it
}

if (a.indexOf("aB") < 0) { 
    // not found
}
if (a.indexOf( "aB" ) == -1) { 
    // not found
}

ただし、次のように~を介して行う方が簡単です

var a = "Hello Baby";

~a.indexOf("Ba");         // -7   -> truthy
if (~a.indexOf("Ba")) {   // true
    // found it
}

~a.indexOf("aB");         // 0    -> falsy
!~a.indexOf("aB");        // true
if (!~a.indexOf( "aB" )) {  // true
    // not found
}

あなたはJSを知らない:カイル・シンプソンによるタイプと文法

23
zangw

~indexOf(item)は非常に頻繁に登場し、ここでの答えは素晴らしいものですが、一部の人々は単にそれを使用して理論を「スキップ」する必要があるだけかもしれません。

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }
20
Jorge Bucaran

チルダトリックを使用してindexOfの結果からtruthy値を作成することを検討している場合、代わりに includesStringメソッド

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

これはES 2015の新しい標準メソッドであるため、古いブラウザーでは機能しないことに注意してください。それが重要な場合は、 String.prototype.includes polyfill の使用を検討してください。

この機能は、 同じ構文 を使用する配列でも使用できます。

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

古いブラウザのサポートが必要な場合の Array.prototype.includes polyfill は次のとおりです。

11
Dana Woodman