【发布时间】:2012-08-31 05:58:19
【问题描述】:
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
我在一个答案中看到过,以前从未见过。
什么意思?
【问题讨论】:
标签: javascript syntax bit-manipulation
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
我在一个答案中看到过,以前从未见过。
什么意思?
【问题讨论】:
标签: javascript syntax bit-manipulation
~ 是一个 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() 的 found 返回值转换为 truthy 也是一个(通常)不清楚的技巧(同时使 not found as falsy)并且人们经常使用它来将数字截断为 32 位(并通过将其加倍来删除小数位,实际上与 Math.floor() 相同的正数)数)。
我说不清楚是因为它的用途不是很明显。通常,您希望您的代码与阅读它的其他人清晰地交流。虽然使用~ 可能看起来很酷,但它通常太聪明了。 :)
现在 JavaScript 有 Array.prototype.includes() 和 String.prototype.includes() 也不再那么重要了。这些返回一个布尔值。如果您的目标平台支持它,您应该更喜欢它来测试字符串或数组中是否存在值。
【讨论】:
value = value || default 是一个常见且有效的习语,只要你知道什么时候可以使用,什么时候不可以使用。
v = t ? a : b;。我发现这比var v; if (t} { v = a; } else { v = b; } 清晰得多,通常跨越 5 行以上,也比var v = b; if (t) { v = a; } 更清晰,var v = b; if (t) { v = a; } 通常是 4 行以上。但我知道很多人不熟悉? : 运算符,他们更喜欢第二种或第三种方式。我发现第一个更具可读性。我同意一般原则,使代码清晰,不要使用黑客。我想我只是看到~v.indexOf('...') 非常清楚,一旦我学会了它。
~ 惯用语。从技术上讲,它是语言 spec 的一部分,但它并不是 一般使用的语言 的一部分。
在 indexOf() 表达式之前使用它可以有效地为您提供真/假结果,而不是直接返回的数字索引。
如果返回值为-1,那么~-1就是0,因为-1是一个全为1的字符串。任何大于或等于零的值都将给出非零结果。因此,
if (~someString.indexOf(something)) {
}
将导致if 代码在“someString”中存在“something”时运行。如果您尝试将.indexOf() 直接用作布尔值,那么这将不起作用,因为有时它会返回零(当“某物”位于字符串的开头时)。
当然,这也有效:
if (someString.indexOf(something) >= 0) {
}
而且它没有那么神秘。
有时您还会看到:
var i = ~~something;
像这样使用~ 运算符两次是一种将字符串转换为32 位整数的快速方法。第一个~ 进行转换,第二个~ 将位翻转回来。当然,如果将运算符应用于无法转换为数字的内容,则结果是 NaN。 (edit——实际上是第二个~首先应用,但你明白了。)
【讨论】:
~对整数执行时等于-(x + 1)。
0 是 false 和非零是 true 的传统可以追溯到很久以前,至少可以追溯到 70 年代的 C 并且可能还有许多其他当时的当代系统编程语言。它可能源于硬件的工作方式;很多CPU在一个操作后会设置一个0位,并有相应的分支指令来测试它。
| 0,在这种情况下它只有一个操作。
~~ 的简单应用程序。
~ 是 Bitwise NOT Operator,~x 与 -(x+1) 大致相同。它更容易理解,有点。所以:
~2; // -(2+1) ==> -3
考虑-(x+1)。 -1 可以执行该操作以生成 0。
换句话说,~ 与一系列数值一起使用只会为-1 输入值生成虚假(从0 强制转换为false)值,否则,任何其他真实值。
众所周知,-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
}
【讨论】:
-(x+1),我会再看一遍。波浪号确切地告诉我它正在做什么来补偿 Javascript 的基于 0 的性质。 另外,括号越少阅读效果越好
if (a.indexOf("Ba") > -1) {// found} //true 键入更少的内容,虽然比波浪号示例有点长,但比您提供的两个示例要少得多,对于新程序员var opinion = !~-1 ? 'more' : 'less'可以理解。
~indexOf(item) 经常出现,这里的答案很好,但也许有些人只需要知道如何使用它并“跳过”理论:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
【讨论】:
++ 和 --,因为它们“鼓励过度狡猾”,但不知何故 ~ 幸存下来(潜伏在阴影中)github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0 或... > -1,因为javascript 是从零开始的,并且从一开始就没有选择解决这个问题。此外,只是意见(与 Airbnb 的相同),任何在 javascript 中做任何有意义的事情的人都知道++,虽然-- 不太常见,但可以推断其含义。
map、forEach 等原始方法,我个人暂时不需要++ 和--。我的观点更多的是关于为什么他们不考虑~ 在任何标准时都过于棘手used 包括递增和递减运算符。禁止某些事情,因此 CIS101 没有任何意义。
对于那些考虑使用波浪号技巧从 indexOf 结果中创建 truthy 值的人来说,使用 includes method on String 来代替它更明确且魔力更小。
'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。
【讨论】: