今天我正在查看一个在线游戏物理库,发现了~~操作符。我知道单个~是按位取反,那么~~是不是对一个非操作再做一次非操作,从而返回相同的值呢?
~~
还可以用作对象中计数器更新的运算符。对未定义的对象属性应用 ~~
将解析为零,并且如果该计数器属性已经存在,则将解析为相同的整数,然后您可以将其递增。let words=["abc", "a", "b", "b", "bc", "a", "b"];
let wordCounts={};
words.forEach( word => wordCounts[word] = ~~wordCounts[word] + 1 );
console.log("b count == " + wordCounts["b"]); // 3
wordCounts[word] = (wordCounts[word] ? wordCounts[word] : 0) + 1;
wordCounts[word] = ~~wordCounts[word] + 1;
如果你想确保负号也被移除,可以使用 Math.abs(Math.trunc(-0.123))
。
~~(-1.23)
返回 -1, 而 Math.abs(Math.trunc(-1.23))
返回 1。 - Mathieu CAROFF~~
是两个一元的按位非运算符放在一起。
这被用作 Math.floor()
的一个更短和通常更快的替代方法,适用于小的正数。由于它还执行了一个转换为数字的步骤,因此它也可以用作 parseInt
的替代方法,尽管 ~~
会产生 0,而 parseInt
会产生 NaN
,例如:~~("a1")
得到 0
,而 parseInt("a1")
得到 NaN
。另请参见这个 任何类型转数字的转换表。
对于可以是负数的小数,它等同于 Math.trunc()
:它删除小数点右侧的所有内容。
对于绝对值大于2 ** 31
(2_147_483_648
)的数字,按位非“溢出”,使用两次会得到一个符号和值都不正确的数字:
~~(2 ** 31)
得到 -2_147_483_648
~~(2 ** 31 + 1)
得到 -2_147_483_647
更深入地了解,~
计算一个数的 32 位整数部分的按位补码。两次运行只留下一个 32 位整型转换。还可以查看此运算符的 规范 和 MDN 文档。