回答:
~
あるビット演算子オペランドのすべてのビットを反転です。
たとえば、数値がである場合1
、IEEE 754浮動小数点のバイナリ表現(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つの可能なツールとして)、パフォーマンスを向上させることができます。
また、(一般的に)不明だトリックオンにするindexOf()
の見つかっに戻り値をtruthy(ながら見られないようfalsy、)と人々はしばしば32ビットに番号を切り捨て(と、それを2倍にすることにより、その小数点以下を落とし、その副作用のためにそれを使用します実質的に同じMath.floor()
正の数です)。
それが何に使われているのかすぐにはわからないので、私は不明確だと言います。一般的に、コードはそれを読んでいる他の人と明確に通信したいとします。使用~
することはクールに見えるかもしれませんが、一般的にそれ自体のためにはあまりにも賢いです。:)
また、JavaScriptにはとがあるためArray.prototype.includes()
、関連性は低くなっていますString.prototype.includes()
。これらはブール値を返します。ターゲットプラットフォームがサポートしている場合は、文字列または配列内の値の存在をテストするためにこれを優先する必要があります。
value = value || default
、いつJavaScriptを使用できるか、使用できないかがわかっている限り、JavaScriptは一般的で有効なイディオムです。
v = t ? a : b;
です。var v; if (t} { v = a; } else { v = b; }
通常、5行以上にまたがって分割されるよりもはるかに明確であり、通常はvar v = b; if (t) { v = a; }
4行以上に分割される場合よりも明確です。しかし、私? :
は2番目または3番目の方法を好むオペレーターに精通していない多くの人々を知っています。最初の方が読みやすいです。私は一般原則に同意し、コードを明確にし、ハックを使用しません。私~v.indexOf('...')
はそれを学んだ後、私は非常に明確に見えると思います。
~
慣用句を呼ばないでしょう。技術的には言語仕様の一部ですが、一般的に使用される言語の一部ではありません。
前にそれを使用して indexOf()
式のと、直接返される数値インデックスの代わりに、真実/偽の結果が得られます。
戻り値がの場合-1
、それ~-1
はがすべて1ビットのストリングである0
ため-1
です。ゼロ以上の値を入力すると、ゼロ以外の結果になります。したがって、
if (~someString.indexOf(something)) {
}
if
「something」が「someString」にあるときにコードを実行させます。使用しようとすると.indexOf()
ブール値として直接と、ゼロが返される場合があるため、機能しません(「何か」が文字列の先頭にある場合)。
もちろん、これも機能します:
if (someString.indexOf(something) >= 0) {
}
そしてそれはかなり不思議ではありません。
時々これも見るでしょう:
var i = ~~something;
この~
ように演算子を2回使用すると、文字列を32ビット整数にすばやく変換できます。1つ目~
は変換を行い、2つ目~
はビットを元に戻します。もちろん、数値に変換できないものに演算子を適用するNaN
と、結果が得られます。(編集 -実際に~
は最初に適用されるのは2番目ですが、あなたはそのアイデアを理解します。)
~
、整数で実行した場合はに等しくなり-(x + 1)
ます。
0
存在することfalse
と非存在でないことの伝統はtrue
、少なくとも70年代のCやおそらく他の多くの当時のシステムプログラミング言語にさかのぼります。それはおそらくハードウェアが機能する方法に由来します。多くのCPUは、操作後にゼロビットを設定し、それに対応する分岐命令をテストします。
| 0
です。その場合、その操作は1つだけです。
~~
同じ方法の単純なアプリケーションを解釈しないことを必ずしも信頼できるわけではありません。
これ~
はビットごとのNOT演算子で、~x
とほぼ同じ-(x+1)
です。理解しやすいですね。そう:
~2; // -(2+1) ==> -3
考えてください-(x+1)
。-1
その操作を実行してを生成できます0
。
言い換えると、~
数値の範囲で使用すると、入力値に対してのみ偽の(false
からに強制される0
)値が生成され-1
ます。それ以外の場合は、他の真の値が生成されます。
ご存知のように、-1
は一般的にセンチネル値と呼ばれます。それは返す多くの機能のために使用される>= 0
の値を成功し、-1
ために失敗 C言語インチ indexOf()
JavaScriptの戻り値の同じルール。
この方法で別の文字列内の部分文字列の有無をチェックすることは一般的です
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
}
-(x+1)
ifステートメントで見た場合、もう一度見てみましょう。チルダは、Javascriptの0ベースの性質を補うために何をしているのかを正確に教えてくれます。また、括弧が少ないほど読みやすくなります
if (a.indexOf("Ba") > -1) {// found} //true
は、チルドの例より少し長いものの、入力した数を少なくすることができます。チルドの例は、2つの例よりもかなり少なく、新しいプログラマにとってはvar opinion = !~-1 ? 'more' : 'less'
わかりやすいでしょう。
~indexOf(item)
かなり頻繁に出てきて、ここでの答えは素晴らしいですが、たぶんそれを使う方法を知り、理論を「スキップ」する必要がある人もいるでしょう。
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
せ--
ず、「過度のトリッキーを奨励する」ため、何とか~
生き残った(影に潜んでいる)github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
か、... > -1
Javascriptをゼロベースであり、最初からこの問題に対処することを選択しなかったので。さらに、意見(Airbnbのものと同じ)だけでも、JavaScriptで意味のあることをしている人なら誰でも知っており++
、--
あまり一般的ではありませんが、その意味を推測できます。
++
ありませんでした--
が、しばらくの間map
、forEach
などのプリミティブメソッドが原因で~
使用されています。私の基準は、使用される標準にインクリメントおよびデクリメント演算子が含まれている場合に、過度にトリッキーだと見なされなかった理由についてです。CIS101が意味をなさないように何かを禁止すること。
ティルダトリックを使用してindexOf
結果から真の値を作成することを検討している場合、代わりにincludes
onメソッドをString
使用する方がより明示的であり、魔法が少なくなります。
'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は次のとおりです。