Javascript 当波浪线位于表达式之前时,它做什么?

Javascript 当波浪线位于表达式之前时,它做什么?,javascript,syntax,bit-manipulation,Javascript,Syntax,Bit Manipulation,我在回答中看到了,我以前从未见过 它是什么意思?~是一个翻转其操作数中所有位的函数 例如,若您的数字是1,则其二进制表示形式(JavaScript如何处理数字)将是 var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() ) ? 'value' : 'innerHTML' 因此,~将其操作数转换为32位整数(JavaScript中的按位运算符可以这样做) 如果它是一个负数,

我在回答中看到了,我以前从未见过

它是什么意思?

~
是一个翻转其操作数中所有位的函数

例如,若您的数字是
1
,则其二进制表示形式(JavaScript如何处理数字)将是

var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'
因此,
~
将其操作数转换为32位整数(JavaScript中的按位运算符可以这样做)

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

…然后翻转它的所有部分

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

它有很多用途。如果你写的是低级的东西,它很方便。如果您分析了您的应用程序并发现了瓶颈,那么可以通过使用位技巧(作为一个大得多的包中的一个可能的工具)来提高它的性能

indexOf()
的find返回值转换为truthy(同时将not found设置为falsy)也是一个(通常)不清楚的把戏,人们经常使用它的副作用是将数字截断为32位(并通过加倍来降低小数位数,实际上与
Math.floor()
正数相同)

我之所以说不清楚,是因为目前还不清楚它的用途。通常,您希望您的代码能够与阅读它的其他人清楚地进行通信。虽然使用
~
看起来很酷,但总的来说它太聪明了


现在JavaScript已经和了,它也不再那么重要了。它们返回一个布尔值。如果您的目标平台支持它,您应该更喜欢使用它来测试字符串或数组中是否存在值。

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

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

1111 1111 1111 1111 1111 1111 1111 1110
当“something”中有“something”时,将导致
if
代码运行。如果您试图直接将
.indexOf()
用作布尔值,那么这将不起作用,因为有时它会返回零(当字符串开头是“something”时)

当然,这也是可行的:

if (~someString.indexOf(something)) {
}
而且它也不那么神秘

有时您还会看到:

if (someString.indexOf(something) >= 0) {
}
像这样使用
~
操作符两次是将字符串转换为32位整数的一种快速方法。第一个
~
进行转换,第二个
~
将位翻转回来。当然,如果运算符应用于无法转换为数字的对象,则会得到
NaN
。(编辑-实际上这是第二个
~
首先应用,但你明白了。)

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

var i = ~~something;
~
是,
~x
-(x+1)
大致相同。有点容易理解。因此:

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }
考虑
-(x+1)
<代码>-1可以执行该操作以生成
0

换句话说,
~
与一系列数值一起使用时,将仅为
-1
输入值生成一个falsy(强制为
false
)值,否则,将生成任何其他真实值

我们知道,
-1
通常被称为哨兵值。它用于在C语言中返回
=0
值表示成功,返回
-1
值表示失败的许多函数。这与JavaScript中的返回值规则相同

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

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

对于那些考虑使用tilde技巧从结果的索引创建真实值的人来说,它更显式,使用tilde技巧的魔力更小

请注意,从ES 2015开始,这是一种新的标准方法,因此在较旧的浏览器上不起作用。在那些重要的情况下,考虑使用

此功能也可用于使用以下各项的阵列:


如果您需要旧版浏览器支持,请参阅下面的

对于那些不想逐位求反的人来说,
~
对整数执行时等于
-(x+1)
。看起来,你知道,负数值首先也应该返回负布尔值。但是,我想,只是JS中的另一个失败了?@adlwalrus那么,
0
false
和非零为
true
的传统可以追溯到很久以前,至少可以追溯到70年代的C语言,可能还有很多其他当时的系统编程语言。它可能源于硬件的工作方式;许多CPU在一个操作后设置一个零位,并有相应的分支指令来测试它。将其转换为32位整数的更快方法是
|0
,在这种情况下,它只有一个操作。@alex确实,虽然我们不一定相信运行时不会以完全相同的方式解释一个简单的
~
应用程序,但“讨厌”这个词对吗?如果它行得通的话,我就称之为该语言的习语。有很多成语。一旦你学会了它们,它们就不那么清晰了。列表理解在Python中是不清楚的,如果您不了解它们,可以通过更详细的循环来完成,但是您永远不会要求Python程序员不使用它们。类似地,JavaScript中的
value=value | | | default
也是一个常见而有效的习惯用法,只要你知道什么时候可以使用它,什么时候不能使用它。@gman我想有人使用它与否并不重要。我认为将列表理解(语言特性)与此进行比较并不是一回事(避免键入额外字符的聪明方法)。如果你认为“肮脏”这个词太苛刻,请随意编辑我的答案。也许是一个更常见的前男友
~2;    // -(2+1) ==> -3
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
}
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false