-1でない
JavaScriptでは indexOfのように対象が見つからなかった場合にだけ-1を返却するようなメソッドがあります。
もちろん、普通に-1であるかどうかを見れば判定する事ができます。
let str = 'abcabcabc';
if(str.indexOf('z') === -1){
console.log('not found z');
}
同じ事をビットの反転演算~
と論理演算の否定!
を使って以下のようにも記述できます。
let str = 'abcabcabc';
if(!~str.indexOf('z')){
console.log('not found z');
}
先頭に!~
を付けると-1の場合にだけtrue、それ以外でfalseなるという事ですね。
順を追ってみていくと次のようになっています。まず、整数値のビットを反転しているのですが、これは符号を反転させ-1を引いた値になります。
for(let i = -2;i <= 2 ;i++){
console.log(`i = ${i} = 0b${(i >>> 0).toString(2)} => ~a = 0b${(~i >>> 0).toString(2)} = ${~i}`);
// "i = -2 = 0b11111111111111111111111111111110 => ~a = 0b1 = 1"
// "i = -1 = 0b11111111111111111111111111111111 => ~a = 0b0 = 0" ⭐
// "i = 0 = 0b0 => ~a = 0b11111111111111111111111111111111 = -1"
// "i = 1 = 0b1 => ~a = 0b11111111111111111111111111111110 = -2"
// "i = 2 = 0b10 => ~a = 0b11111111111111111111111111111101 = -3"
}
つまり、0になるのは、-1をビット反転した場合という事になります。
論理演算の否定!
は、対象の真偽値を逆転します。
数値をbooleanとして評価すると0の場合だけfalseとなるので、
結局!~
は-1の場合にだけtrueを返却します。
for(let i = 1;i >= -3 ;i--){
console.log(`i = ${i} => !${i} = ${!i}`);
// "i = 1 => !1 = false"
// "i = 0 => !0 = true" ⭐
// "i = -1 => !-1 = false"
// "i = -2 => !-2 = false"
// "i = -3 => !-3 = false"
}