!!~(不是波浪号/bang bang 波浪号)如何改变“包含/包含”数组方法调用的结果?

IT技术 javascript jquery operators bitwise-operators
2021-03-07 21:26:03

如果您在这里阅读 jQueryinArray页面的评论,会发现一个有趣的声明:

!!~jQuery.inArray(elm, arr) 

现在,我相信双感叹号会将结果转换为 type 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

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

6个回答

您有时会看到~应用在$.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
}

它会按预期工作。

如果像这样的基本操作不完美,我会感到惊讶。
2021-04-26 21:26:03
这在浏览器中的支持程度如何(现在是 2014 年?)还是一直完美支持?
2021-05-10 21:26:03

!!~expr评估为falsewhen expris -1else 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

以外的值-1将具有至少一个比特设置为零; 反转它会创造一个真实的value;!运算符两次应用于真值返回布尔值真。

当与.indexOf()and 一起使用时,我们只想检查结果是否为-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评估为 false 所以这个厌恶不能可靠地用于测试-1.

严格来说,>= 0!!~. !== -1更近了。
2021-04-21 21:26:03
这不是问题……至少在要求其他人继续使用您的代码之前是这样。
2021-04-30 21:26:03
在一个稳定的库中,我认为使用没有问题~foo.indexOf(bar),它不会显着节省字符或性能,但它是一种相对常见的速记方式foo = foo || {}
2021-05-02 21:26:03
@ahsteele,我很清楚这条规则,但是按位运算符是我能想到的每种编程语言的一部分。我尝试以一种可以阅读代码的人可读的方式进行编程我不会仅仅因为其他人不理解而停止使用一种语言的功能,否则我什至无法使用!!.
2021-05-08 21:26:03

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

参见波浪号的伟大之谜(~)

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

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

固定的!(将其更改为另一个链接,奇怪的是,它是在我原来的答案之后写的......)
2021-04-19 21:26:03

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

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

+1 这个答案比公认的答案更好地解释了“为什么”。
2021-04-25 21:26:03

jQuery.inArray()返回-1“未找到”,其补码 ( ~) 为0因此,为“未找到”~jQuery.inArray()返回一个假值 ( 0),为“找到”返回一个真值(一个负整数)。!!然后将 falsy/truthy 形式化为真正的 boolean false/ true因此,!!~jQuery.inArray()将给出true“找到”和false“未找到”。