谁会想到 JavaScript 罕见而神秘的按位运算符会如此有用?不久前,我第一次发现这个技巧是在 Thomas Fuchs 的 JavaScript 性能幻灯片中。“诀窍”如下:
~~something;
按位取反运算符 ( ~ ) 将获取其操作数,将其转换为 32 位整数,并将反转每个位,使每个 0 位都变成 1 ,反之亦然。
00000000000000000000000000001001
...becomes
11111111111111111111111111110110
给定表达式 ~foo ,其效果为 -(foo + 1) 。因此,双位按位取反运算 ( ~~foo ) 将导致 -(-(foo + 1) + 1) 。不过,这仅适用于整数;给定所有潜在的操作数,实际等效表达式~~ 可能是这样的:
typeof foo === 'number' && !isNaN(foo) && foo !== Infinity ? foo > 0 ? Math.floor(foo) : Math.ceil(foo) : 0;
// This is ONLY _effectively_ the same... this is
// NOT what happens internally!
这显然比 ~~ 慢了不少。
如果操作数是一个数字,而它不是 NaN , Infinity 则 ~~ 将产生将其四舍五入为零的效果。如果它不是数字,那么我相信内部 ToInt32 函数会将其转换为零。
以下是 ~~ 操作的一些示例:
~~null; // => 0
~~undefined; // => 0
~~0; // => 0
~~{}; // => 0
~~[]; // => 0
~~(1/0); // => 0
~~false; // => 0
~~true; // => 1
~~1.2543; // => 1
~~4.9; // => 4
~~(-2.999); // => -2