如果您阅读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
我不明白这里代字号的目的。有人可以解释一下或指向我的资源吗?
答案 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
false
为expr
时,{p> -1
评估为true
。expr != -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。在这种情况下,它用于强制函数的输出为true
或false
。
答案 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