当代数在表达式之前时,代字号会做什么?

时间:2012-09-06 12:02:25

标签: javascript syntax bit-manipulation

var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
           ? 'value'
           : 'innerHTML'

我在一个答案中看到了它,我以前从未见过它。

这是什么意思?

5 个答案:

答案 0 :(得分:243)

~bitwise operator,它会翻转其操作数中的所有位。

例如,如果您的号码为1,则其IEEE 754 float的二进制表示形式(JavaScript如何处理数字)将是......

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

所以~将其操作数转换为32位整数(JavaScript中的按位运算符)...

0000 0000 0000 0000 0000 0000 0000 0001

如果是负数,则将其存储在2的补码中:反转所有位并加1。

...然后翻转所有位......

1111 1111 1111 1111 1111 1111 1111 1110
  

那么它的用途是什么呢?什么时候可以使用它?

它有很多用途。如果你正在编写低级别的东西,它很方便。如果您分析了应用程序并发现了瓶颈,那么可以通过使用按位技巧(在更大的包中作为一个可能的工具)来提高性能。

indexOf()找到的返回值转换为 truthy (同时制作< em> not found as falsy )人们常常将它用于将数字截断为32位的副作用(并通过将其加倍来删除小数位,实际上与{{1相同)对于正数)。

我说不清楚,因为它并不是很明显它用于什么。通常,您希望您的代码能够清楚地与其他人阅读。虽然使用Math.floor()可能看起来很酷,但它通常对自己的好处太聪明了。 :)

现在JavaScript已经Array.prototype.includes()String.prototype.includes()的关联性也降低了。这些返回一个布尔值。如果您的目标平台支持它,您应该更喜欢这个来测试字符串或数组中是否存在值。

答案 1 :(得分:96)

indexOf()表达式之前使用它会有效地为您提供真实/错误的结果,而不是直接返回的数字索引。

如果返回值为-1,则~-10,因为-1是一个全1位的字符串。任何大于或等于零的值都将给出非零结果。因此,

if (~someString.indexOf(something)) {
}
当“someString”中出现“something”时,

将导致if代码运行。如果你试图直接使用.indexOf()作为布尔值,那么这将不起作用,因为有时它返回零(当“某事物”在字符串的开头)。

当然,这也有效:

if (someString.indexOf(something) >= 0) {
}

并且它不那么神秘。

有时你也会看到这个:

var i = ~~something;

使用~运算符两次这样可以快速将字符串转换为32位整数。第一个~执行转换,第二个~将位翻转。当然,如果操作符应用于无法转换为数字的内容,则会得到NaN。 (编辑 - 实际上它是第一个应用的~,但你明白了。)

答案 2 :(得分:23)

~Bitwise NOT Operator~x-(x+1)大致相同。它更容易理解。所以:

~2;    // -(2+1) ==> -3

考虑-(x+1)-1可以执行该操作以生成0

换句话说,~与一系列数字值一起使用,只会对false输入值产生假(从0强制-1)值,否则,任何其他真实的价值。

众所周知,-1通常称为哨兵值。它用于许多函数,这些函数在C语言中为成功返回>= 0值,为失败返回-1。与JavaScript中indexOf()的返回值相同的规则。

通常以这种方式检查另一个字符串中是否存在子字符串

var a = "Hello Baby";

if (a.indexOf("Ba") >= 0) {
    // found it
}
if (a.indexOf("Ba") != -1) { 
    // found it
}

if (a.indexOf("aB") < 0) { 
    // not found
}
if (a.indexOf( "aB" ) == -1) { 
    // not found
}

但是,通过~进行下面的

会更容易
var a = "Hello Baby";

~a.indexOf("Ba");         // -7   -> truthy
if (~a.indexOf("Ba")) {   // true
    // found it
}

~a.indexOf("aB");         // 0    -> falsy
!~a.indexOf("aB");        // true
if (!~a.indexOf( "aB" )) {  // true
    // not found
}

You Don't Know JS: Types & Grammar by Kyle Simpson

答案 3 :(得分:20)

~indexOf(item)经常会出现,这里的答案很棒,但也许有些人只需要知道如何使用它,并且&#34;跳过&#34;理论:

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }

答案 4 :(得分:11)

对于那些考虑使用代字号技巧从indexOf结果创建 truthy 值的人来说,它更明确,而且使用includes method on String的魔法更少。< / p>

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

请注意,这是ES 2015中的一种新标准方法,因此它不适用于旧版浏览器。如果重要,请考虑使用String.prototype.includes polyfill

此功能也可用于使用same syntax的数组:

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

如果您需要较旧的浏览器支持,这是Array.prototype.includes polyfill