javascriptの中のビットを逆に取ります.


今日プロジェクトでこのようなコードが見られました.
if(~key.indexOf('I')){
    priceTagData.adulti = {
        tag: key,
        price: value
    }
}
この操作符にはこの上もないなじみがあります.もちろん作者の意図が分かりません.今は本人の知識欲が旺盛なので、この操作符の使い方を勉強することにしました.
ES 5を見ましたが、元はビットがアンチオペレータです.以下はES 5の操作子に対する説明です.
Bitwise NOT Operator(~)
The production Uniary Expression:~ UniveryExpression is evaluated as follows:
  • Let expr be the result of evaluating UniaryExpression.
  • Let oldValue be ToInt 32(GetValue(expr).
  • Return the relt of appying bitwise complement to oldValue.The reult is a signed 32-bitinteger.
  • 大体の価値を求める過程は以下の通りです.
    1.まず値を求めます.右の表現は、値を求める結果をexprとします.
    2.ToInt 32(expr)を実行し、戻り結果をoldValueとする.
    ECMAScriptのNumberタイプの格納フォーマットは64ビット浮動小数点なので、ビット操作を行う前に浮動小数点を32ビットの符号付き整数に変換します.つまり、上で説明したToInt 32の方法です.ToInt 32は定義された内部タイプの変換方法を規範化しています.ECMAScriptプログラム利用者は直接起動できません.ToInt 32はここで詳しく説明します.
    3.oldValueをビットで反転して返します.
    32ビットの整数を返しますので、この整数を64ビットの浮動小数点に変換する必要があります.したがって、ECMAScriptのビット操作は、c++のように直接ビットを操作するのではなく、ビット操作の前と後に浮動小数点を整数と整数に変換して浮動小数点にする操作が必要である.
    具体例を見てみます.~4294962318、上の仕様の定義によって結果を淫らにします.
    まず値を求めます.右の表現は、値を求めると4294962318です.
    その後、ToInt 32を実行し(4294962318)、
    ToInt 32の内部実行プロセスは、
    4294962318をToNumber変換し、結果は依然として4294962318である.
    シークsign(4294962318)*flor(abs(4294962318))は、結果は依然として4294962318です.
    シーク4294962318 modulo 4294967296(2^32)の値は、結果4294962318です.
    4294962318は2147483648(2^31)より大きいので、4294962318-4294967296を返します.つまり-4978です.
    sign,flor,abs,modulo用法参照->ここ
    次は-4978を2進に変換します.便利さのために、10進を2進に変換して、下はc+ソースで、添付ファイル(ダウンロードしてファイルに追加します.exe拡張子)をご覧ください.このプログラムで変換したい数字を変換できます.
    #include 
    using namespace std;
    int main () {
     int t;
     cout << "        2         :";
     cin >> t;
     char str[255];
     itoa(t, str, 2);
     cout << str << endl;
     system("pause");
     return 0;
    }
    -4978はバイナリで表されています. 1111 1111 1111 1111 1110 1100 1000 1110
    逆の位を取ればいいです.          0000 0000 0001 0011 0111 0001
    これは逆取りした結果、理論的には~4294962318で計算された値です.
    続いて、私達はjsコンソールで実行します.4294962318、4977を得ます.
    4977をプログラムでバイナリに変換します.結果は0000 00001 0011 0001です.
    あなたは私たちが導いたバイナリと同じであることを発見します.
    理論と実践を話した後、最初の問題に戻ります.
    if(~key.indexOf('I')) {
    何をしたいですか?
    indexOfは、入力された文字列の最初の位置を検索するための文字列の一つの方法であることを知っているはずです.ある場合は、文字列のインデックス値を返します.
    ~-1はちょうど0に等しく、0はECMAScript ifの条件の中でfalseに相当し、0以外はtrueに相当します.ついに!著者の意図が分かりました.つまり、key文字列にIが含まれている場合はif条件でtrueの文を実行します.Iが含まれていない場合はif条件でtrueの文を実行しません.
    このようなかっこいい書き方と同等の意味での無意味な書き方は以下の通りです.
    if(key.indexOf('I') !== -1){
        saveTheEarth();
    }
    最後はツッコミの時間です...
    私個人はこのような奇妙な書き方にあまり賛成していません.jserは通常のプログラミングの中でビット操作が必要なところはまだ少ないですから、複数のプロジェクトの中でこのようなコードを書いたら、後で他の人がこのコードを維持しに来た時、霧が感じられます.知らず知らずのうちにプロジェクトの維持の難しさとコストが増加しました.