215
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'

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

这是什么意思?

4

5 回答 5

294

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

例如,如果您的数字是,它的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

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

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

这也是一个(通常)不清楚的技巧,将indexOf()'s found返回值变为值(同时将not found设为falsy),人们经常使用它来将数字截断为 32 位(并通过将其加倍来删除小数位,实际上与正数相同)。Math.floor()

我说不清楚,因为它的用途并不是很明显。通常,您希望您的代码与阅读它的其他人清晰地交流。虽然使用~可能看起来很酷,但它通常太聪明了。:)

现在 JavaScript 具有Array.prototype.includes()String.prototype.includes(). 这些返回一个布尔值。如果您的目标平台支持它,您应该更喜欢它来测试字符串或数组中是否存在值。

于 2012-09-06T12:03:05.703 回答
128

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

如果返回值为-1,那么~-10因为-1是一个全为 1 位的字符串。任何大于或等于零的值都将给出非零结果。因此,

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

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

当然,这也有效:

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

而且它的神秘程度要低得多。

有时你还会看到:

var i = ~~something;

像这样使用~运算符两次是一种将字符串转换为 32 位整数的快速方法。第一个~进行转换,第二个~将位翻转回来。当然,如果将运算符应用于无法转换为数字的内容,您会得到NaN结果。(编辑——实际上它~是首先应用的第二个,但你明白了。)

于 2012-09-06T12:04:56.683 回答
35

~is Bitwise NOT 运算符,与.~x大致相同-(x+1)。它更容易理解,有点。所以:

~2;    // -(2+1) ==> -3

考虑-(x+1)-1可以执行该操作以生成0.

换句话说,~与一系列数值一起使用只会为输入值产生一个虚假(强制转换为falsefrom )值,否则,任何其他真实值。0-1

众所周知,-1通常称为哨兵值。它用于许多在 C 语言中返回成功失败>= 0值的函数。与JavaScript中的返回值规则相同。-1indexOf()

通常以这种方式检查另一个字符串中是否存在子字符串

var a = "Hello Baby";

if (a.indexOf("Ba") >= 0) {
    // found it
}
if (a.indexOf("Ba") != -1) { 
    // found it
}

if (a.indexOf("aB") < 0) { 
    // not found
}
if (a.indexOf( "aB" ) == -1) { 
    // not found
}

~但是,通过以下方式更容易做到这一点

var a = "Hello Baby";

~a.indexOf("Ba");         // -7   -> truthy
if (~a.indexOf("Ba")) {   // true
    // found it
}

~a.indexOf("aB");         // 0    -> falsy
!~a.indexOf("aB");        // true
if (!~a.indexOf( "aB" )) {  // true
    // not found
}

你不知道 JS:类型和语法,凯尔·辛普森 (Kyle Simpson)

于 2016-01-11T05:17:44.597 回答
27

~indexOf(item)经常出现,这里的答案很好,但也许有些人只需要知道如何使用它并“跳过”理论:

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }
于 2015-02-27T03:38:08.993 回答
13

对于那些考虑使用波浪号技巧从结果中创建真实值的人来说,使用on 方法indexOf更明确且魔力更小。includesString

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

请注意,这是 ES 2015 的新标准方法,因此不适用于旧版浏览器。如果这很重要,请考虑使用String.prototype.includes polyfill

此功能也可用于使用相同语法的数组:

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

如果您需要旧版浏览器支持,这里是Array.prototype.includes polyfill 。

于 2016-03-03T22:09:35.200 回答