怎么!!〜(不是不是波浪形/爆炸声波)改变'包含/包含'数组方法调用的结果?

use*_*236 93 javascript jquery operators bitwise-operators

如果您在这里阅读jQuery inArray页面上的注释,那么有一个有趣的声明:

!!~jQuery.inArray(elm, arr) 
Run Code Online (Sandbox Code Playgroud)

现在,我相信双感叹号会将结果转换为类型boolean,值为true.我不明白的是,~在所有这些中使用了tilde()运算符是什么?

var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Run Code Online (Sandbox Code Playgroud)

重构if声明:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Run Code Online (Sandbox Code Playgroud)

分解:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true
Run Code Online (Sandbox Code Playgroud)

我也注意到,如果我把波浪号放在前面,结果是-2.

~!!~jQuery.inArray("one", arr) // -2
Run Code Online (Sandbox Code Playgroud)

我不明白这里代字号的目的.有人可以解释一下或指向我的资源吗?

Yah*_*hel 117

你有时会~在前面看到一个特殊的原因$.inArray.

基本上,

~$.inArray("foo", bar)
Run Code Online (Sandbox Code Playgroud)

是一个较短的方法

$.inArray("foo", bar) !== -1
Run Code Online (Sandbox Code Playgroud)

$.inArray如果找到第一个参数,则返回数组中项的索引,如果未找到,则返回-1.这意味着如果你正在寻找"是数组中的这个值吗?"的布尔值,你就不能进行布尔比较,因为-1是一个真值,当$ .inArray返回0时(一个假值) ),它意味着它实际上在数组的第一个元素中找到.

应用~按位运算符会导致-1变为0,并使0变为-1.因此,没有在数组中找到值并应用按位NOT会导致伪值(0),而所有其他值将返回非0数字,并且将表示真实的结果.

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}
Run Code Online (Sandbox Code Playgroud)

它会按预期工作.

  • 这在浏览器中是否得到了很好的支持(现在在2014年?)或者它是否一直得到完美支持? (2认同)

Sal*_*n A 102

!!~expr计算结果为false,当expr-1,否则true.
它是一样的expr != -1,只有破碎的*


它的工作原理是JavaScript按位运算将操作数转换为二进制补码格式的32位有符号整数.因此!!~-1评估如下:

   -1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
  ~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
   !0 = true                                     // ! is logical not (true for falsy)
!true = false                                    // duh
Run Code Online (Sandbox Code Playgroud)

除了-1将至少一个位设置为零之外的值; 颠倒它将创造一个真正的价值; 将!运算符两次应用于truthy值返回boolean true.

使用时.indexOf(),我们只想检查结果是否-1:

!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns  0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns  1, the expression evaluates to true
Run Code Online (Sandbox Code Playgroud)

*!!~8589934591评估为假,所以这个厌恶不能可靠地用于测试-1.

  • @zzzzBov [扩展Salman's](http://stackoverflow.com/questions/10582286/what-does-mean-in-javascript#comment13710140_10582345)评论:[始终编码,好像最终维护代码的人是暴力精神病患者谁知道你住在哪里.](http://www.codinghorror.com/blog/2008/06/coding-for-violent-psychopaths.html) (9认同)
  • 这不是问题......至少在其他人被要求继续使用您的代码之前. (6认同)

p.g*_*all 55

波浪形运算符实际上并不是jQuery的一部分 - 它本身就是JavaScript中的一个NOT运算符.

参见蒂尔德的神秘之处(〜).

您在实验中得到了奇怪的数字,因为您正在对整数执行按位逻辑运算(据我所知,可能存储为两个补码或类似的东西......)

两个补码解释了如何用二进制表示数字.我想我是对的.

  • 固定!(把它改成另一个链接,奇怪的是,这是我原来的答案之后写的......) (3认同)

zzz*_*Bov 32

~foo.indexOf(bar)是一种常见的简写,foo.contains(bar)因为该contains函数不存在.

通常,由于JavaScript的"虚假"值的概念,强制转换为布尔值是不必要的.在这种情况下,它用于强制函数的输出为truefalse.

  • +1这个答案解释了"为什么"比接受的答案更好. (6认同)

Ama*_*dan 18

jQuery.inArray()返回-1"未找到",其补码(~)为0.因此,~jQuery.inArray()返回0"未找到" 的假值()和"找到"的真值(负整数).!!然后将falsy/truthy形式化为真正的布尔值false/ true.因此,!!~jQuery.inArray()将给予true"发现"和false"未找到".


Min*_*iel 12

~所有4个字节int是等于该式-(N+1)

所以

~0   = -(0+1)   // -1
~35  = -(35+1)  // -36 
~-35 = -(-35+1) //34 
Run Code Online (Sandbox Code Playgroud)

  • 这并不总是正确的,因为(例如)`~2147483648!= - (2147483648 + 1)`. (3认同)

Poi*_*nty 10

~操作是按位补运算符.inArray()当找不到元素时,整数结果为-1,或者是一些非负整数.-1的按位补码(以二进制表示为全1位)为零.任何非负整数的按位补码始终为非零.

因此,!!~itrue当整数"i"是一个非负的整数,并且false当"i"是恰好-1.

请注意,~始终将其操作数强制转换为整数; 也就是说,它强制非整数浮点值为整数,以及非数字值.


Joe*_*Joe 10

Tilde是按位NOT - 它反转值的每一位.作为一般经验法则,如果您使用~数字,其符号将被反转,然后将减去1.

因此,当你这样做时~0,得到-1(0反转为-0,减去1为-1).

它本质上是一种精心设计的超微优化方式,可以获得始终为布尔值的值.


Luk*_*keH 8

你是对的:falseindexOf调用返回-1 时,这段代码将返回; 否则true.

正如你所说,使用类似的东西会更加明智

return this.modifiedPaths.indexOf(path) !== -1;
Run Code Online (Sandbox Code Playgroud)

  • 谁在这里拖钓?;)我想我认为编写可读代码比生成这类问题的神秘预优化代码更好.稍后缩小,现在编写可读,易懂的代码. (2认同)
  • 我个人认为`> -1`更具可读性,但这可能非常主观. (2认同)

Frx*_*rem 6

~操作是按位NOT运算符.这意味着它需要一个二进制形式的数字,并将所有零变为1和1为零.

例如,二进制中的数字0是0000000,而-1是11111111.同样,1是00000001二进制,而-2是11111110.