ビット演算でundefined、NaNを0に変換する
javascriptの算術演算子は(+
が文字列連結の時を除いて)被演算子がundefined
、NaN
の時、結果はNaN
になります。
undefined + 1
//NaN
undefined - 1
//NaN
undefined * 1
//NaN
undefined / 1
//NaN
undefined % 1
//NaN
+undefined
//NaN
-undefined
//NaN
NaN + 1
//NaN
NaN - 1
//NaN
NaN * 1
//NaN
NaN / 1
//NaN
NaN % 1
//NaN
+NaN
//NaN
-NaN
//NaN
ビット演算子の場合、これらが全て0
として扱われます。
undefined ^ 1
// 0 ^ 1 => 1
undefined & 1
// 0 & 1 => 0
undefined | 1
// 0 | 1 => 1
undefined << 1
// 0 << 1 => 0
undefined >> 1
// 0 >> 1 => 0
undefined >>> 1
// 0 >>> 1 => 0
~undefined
// ~0 => -1
NaN ^ 1
// 0 ^ 1 => 1
NaN & 1
// 0 & 1 => 0
NaN | 1
// 0 | 1 => 1
NaN << 1
// 0 << 1 => 0
NaN >> 1
// 0 >> 1 => 0
NaN >>> 1
// 0 >>> 1 => 0
~NaN
// ~0 => -1
下の例はi
が3
、5
、7
、11
で割り切れるか否かが1
、2
、4
、8
のビットに対応しています。
割り切れない場合はundefined
になるので+
で連結すると、NaN
になってしまいます。
var i = 35;
[1][i%3] + [2][i%5] + [4][i%7] + [8][i%11]
// undefined + 2 + 4 + undefined => NaN
ビットフラグの合成などは+
の代わりに|
、^
が使えます。
[1][i%3] | [2][i%5] | [4][i%7] | [8][i%11]
// undefined | 2 | 4 | undefined => 6
[1][i%3] ^ [2][i%5] ^ [4][i%7] ^ [8][i%11]
// undefined ^ 2 ^ 4 ^ undefined => 6
ちなみにnull
は算術演算子でも0
扱いです、
ちょっとずるいです。
null + 1
// 0 + 1 => 1