波浪号在表达式之前时会执行什么操作?

2022-08-30 01:00:41
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'

我在答案中看到了它,我以前从未见过它。

这是什么意思?


答案 1

~是一个按位运算符,可翻转其操作数中的所有位。

例如,如果你的数字是,它对IEEE 754浮点数(JavaScript如何处理数字)的二进制表示形式将是...1

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

因此,将其操作数转换为32位整数(JavaScript中的按位运算符会这样做)...~

0000 0000 0000 0000 0000 0000 0000 0001

如果它是一个负数,它将存储在2的补码中:反转所有位并加1。

...然后翻转它的所有位...

1111 1111 1111 1111 1111 1111 1111 1110

那么,它有什么用呢?什么时候可以使用它?

它有相当多的用途。如果你正在写低级的东西,它很方便。如果您分析了应用程序并发现了瓶颈,则可以通过使用按位技巧(作为更大袋子中的一种可能的工具)来提高其性能。

找到的返回值转换为真实值(同时不被发现虚假)也是一个(通常)不清楚的技巧,人们经常使用它来截断数字到32位的副作用(并通过加倍将其降低小数位,实际上与正数相同)。indexOf()Math.floor()

我说不清楚,因为它不是很明显它的用途。通常,您希望您的代码能够清楚地传达给阅读它的其他人。虽然使用可能看起来很酷,但它通常太聪明了, 因为它本身的好处。:)~

现在JavaScript有Array.prototype.include()和String.prototype.include(也不太重要了。它们返回一个布尔值。如果您的目标平台支持它,您应该更喜欢它来测试字符串或数组中是否存在值。


答案 2

在表达式之前有效地使用它可以有效地为您提供真/假结果,而不是直接返回的数字索引。indexOf()

如果返回值为 ,则 is 是因为 是所有 1 位的字符串。任何大于或等于零的值都将给出非零结果。因此-1~-10-1

if (~someString.indexOf(something)) {
}

将导致代码在“someString”中“某物”时运行。如果您尝试直接用作布尔值,则不起作用,因为有时它返回零(当“something”位于字符串的开头时)。if.indexOf()

当然,这也有效:

if (someString.indexOf(something) >= 0) {
}

而且它远没有那么神秘。

有时您还会看到以下内容:

var i = ~~something;

像这样使用运算符两次是将字符串转换为 32 位整数的快速方法。第一个执行转换,第二个执行位反转。当然,如果运算符应用于无法转换为数字的东西,则结果会得到。(编辑 - 实际上这是第二个首先应用,但你明白了。~~~NaN~