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

时间:2012-02-16 18:08:09

标签: javascript jquery operators bitwise-operators

如果您阅读jQuery inArray页面here上的评论,那就有一个有趣的宣言:

!!~jQuery.inArray(elm, arr) 

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

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

重构if语句:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }

故障:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true

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

~!!~jQuery.inArray("one", arr) // -2

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

13 个答案:

答案 0 :(得分:117)

有一个明确的原因,您有时会在~前面看到$.inArray

基本上,

~$.inArray("foo", bar)

是一种较短的做法

$.inArray("foo", bar) !== -1
如果找到第一个参数,

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

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

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}

它会按预期工作。

答案 1 :(得分:102)

!!~expr falseexpr时,{p> -1评估为trueexpr != -1。 它与!!~-1相同,只有* *


它有效,因为JavaScript bitwise operations将操作数转换为二进制补码格式的32位有符号整数。因此, -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 评估如下:

-1

!以外的值至少有一位设置为零;颠倒它将创造一个真正的价值;将.indexOf()运算符两次应用于truthy值会返回boolean true。

-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

!!~8589934591

* -1的计算结果为false,因此 abomination 无法可靠地用于测试{{1}}。

答案 2 :(得分:55)

tilde运算符实际上并不是jQuery的一部分 - 它本身就是JavaScript本身的一个NOT运算符。

请参阅 The Great Mystery of the Tilde(~)

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

Two's complement 解释了如何用二进制表示数字。我想我是对的。

答案 3 :(得分:32)

~foo.indexOf(bar)是表示foo.contains(bar)的常用简写,因为contains函数不存在。

由于JavaScript的“falsy”值概念,通常不需要强制转换为boolean。在这种情况下,它用于强制函数的输出为truefalse

答案 4 :(得分:18)

jQuery.inArray()为“未找到”返回-1,其补充(~)为0。因此,~jQuery.inArray()返回“未找到”的假值(0)和“找到”的真值(负整数)。然后!!会将falsy / truthy形式化为真正的布尔值false / true。因此,!!~jQuery.inArray()会为“已找到”提供true,为“未找到”提供false

答案 5 :(得分:12)

所有4个字节~的{​​{1}}等于此公式int

<强> SO

-(N+1)

答案 6 :(得分:10)

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

因此,当整数“i”是非负整数时,!!~i将为true,而当“i”恰好为-1时,false将为~

注意{{1}}总是将其操作数强制转换为整数;也就是说,它强制非整数浮点值为整数,以及非数字值。

答案 7 :(得分:10)

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

因此,当你执行~0时,得到-1(0反转为-0,减去1为-1)。

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

答案 8 :(得分:8)

你是对的:当false调用返回-1时,此代码将返回indexOf;否则true

正如你所说,使用像

这样的东西会更明智
return this.modifiedPaths.indexOf(path) !== -1;

答案 9 :(得分:6)

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

例如,二进制数0是0000000,而-1是11111111。同样,1是二进制00000001,而-2是11111110

答案 10 :(得分:3)

我的猜测是它存在,因为它有几个字符更短(图书馆作者总是在之后)。它还使用在编译为本机代码时只需几个机器周期的操作(而不是与数字进行比较。)

我同意另一个答案,即它是一种过度杀伤但可能在紧密循环中有意义(但需要进行性能增益估计,否则可能会导致过早优化。)

答案 11 :(得分:2)

我假设,因为它是一个按位运算,它是检查路径是否出现在modifiedPaths中的最快(计算上很便宜)的方法。

答案 12 :(得分:1)

作为(~(-1)) === 0,所以:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false