Javascript-!!〜(不是波浪线/爆炸波浪线)如何改变“包含/包含” Array方法调用的结果?

如果您在此处的jQuery -2页上阅读了注释,则会有一个有趣的声明:

!!~jQuery.inArray(elm, arr) 

现在,我相信双感叹号会将结果转换为true类型的值true。我不知道在所有这些中使用代字号(~)的运算符是什么?

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

重构-2语句:

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个解决方案
117 votes

有一个特定的原因,有时您会在-1前面看到应用~

基本上,

~$.inArray("foo", bar)

是一种较短的方法

$.inArray("foo", bar) !== -1

~如果找到第一个参数,则返回数组中该项的索引,如果找不到第一个参数,则返回-1。 这意味着,如果要查找“此值是否在数组中?”的布尔值,则不能进行布尔值比较,因为-1是真实值,并且$ .inArray返回0(错误值) ),则表示其实际位于数组的第一个元素中。

应用~按位运算符会使-1变为0,并使0变为`-1。 因此,在数组中找不到该值并应用按位NOT不会得出虚假的值(0),其他所有值将返回非0的数字,并表示真实结果。

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

它会按预期工作。

Yahel answered 2020-07-09T16:24:02Z
102 votes

expr-1true时,!!~8589934591评估为-1
它与expr != -1相同,只是已损坏*


之所以起作用,是因为JavaScript按位运算将操作数转换为二进制补码形式的32位有符号整数。 因此对!!~8589934591进行如下评估:

   -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

!!~8589934591以外的其他值将至少有一位设置为零; 反转它会创造一个真实的价值; 将-1运算符两次应用于真实值会返回布尔值true。

当与!!~8589934591一起使用时,我们只想检查结果是否为-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

Salman A answered 2020-07-09T16:24:52Z
55 votes

波浪号运算符实际上根本不是jQuery的一部分-在JavaScript本身中是按位NOT运算符。

参见波浪号大奥秘(〜)。

您在实验中得到的是奇怪的数字,因为您正在对整数执行按位逻辑运算(就我所知,该整数可能存储为二进制补码或类似的数字...)

二进制补码说明了如何用二进制表示数字。 我想我是对的。

p.g.l.hall answered 2020-07-09T16:23:19Z
32 votes

true是表示false的常用缩写,因为contains函数不存在。

由于JavaScript的“伪造”值概念,通常不需要强制转换为布尔值。 在这种情况下,它用于强制功能输出为truefalse

zzzzBov answered 2020-07-09T16:25:17Z
18 votes

jQuery.inArray()针对“未找到”返回-1,其补码(~)为0。因此,~jQuery.inArray()返回“未找到”的虚假值(0),以及对于“找到”的真实值(负整数)。 !!然后将伪造的/真实的布尔值形式化为真实的布尔值false/true。 因此,!!~jQuery.inArray()将为“发现”提供true,并为“未发现”提供false

Amadan answered 2020-07-09T16:25:39Z
12 votes

所有4个字节的~ int等于此公式-(N+1)

所以

~0   = -(0+1)   // -1
~35  = -(35+1)  // -36 
~-35 = -(-35+1) //34 
Mina Gabriel answered 2020-07-09T16:26:03Z
10 votes

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

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

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

Pointy answered 2020-07-09T16:26:32Z
10 votes

波浪号不是按位的-它将值的每一位取反。 作为一般经验法则,如果在数字上使用~0,其符号将被反转,然后将1减去。

因此,当您执行~0时,您将获得-1(0取反为-0,减1为-1)。

从本质上讲,这是获取始终为布尔值的精巧,超微优化的方法。

Joe answered 2020-07-09T16:27:01Z
8 votes

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

正如您所说,使用类似

return this.modifiedPaths.indexOf(path) !== -1;
LukeH answered 2020-07-09T16:27:26Z
6 votes

0000000运算符是按位NOT运算符。 这意味着它采用二进制形式的数字并将所有零变为一,而一个变为零。

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

Frxstrem answered 2020-07-09T16:27:50Z
3 votes

我的猜测是,它在那里是因为它短了几个字符(库作者总是在后面几个字符)。 当编译成本机代码时(与对数字的比较相反),它还使用仅花费几个机器周期的操作。

我同意另一个答案,认为这是一个过大的杀伤力,但也许在一个紧密的循环中可能有意义(不过,需要估算性能增益,否则可能是过早的优化。)

Alexander Pavlov answered 2020-07-09T16:28:16Z
2 votes

我认为,由于这是按位操作,因此它是检查路径是否出现在ModifyPaths中的最快方法(从计算上来说很便宜)。

panos2point0 answered 2020-07-09T16:28:36Z
1 votes

作为(~(-1)) === 0,因此:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false
Engineer answered 2020-07-09T16:28:57Z
translate from https://stackoverflow.com:/questions/10582286/what-does-mean-in-javascript