JavaScript 是什么>>>>运算符以及如何使用它?
我正在查看 Mozilla 中向 Array 添加过滤方法的代码,其中有一行代码让我感到困惑。
var len = this.length >>> 0;
我从来没见过>>>>之前在 JavaScript 中使用过。
它是什么以及它有什么作用?
I was looking at code from Mozilla that add a filter method to Array and it had a line of code that confused me.
var len = this.length >>> 0;
I have never seen >>> used in JavaScript before.
What is it and what does it do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
它不仅将非数字转换为数字,还将它们转换为可以表示为 32 位无符号整数的数字。
尽管 JavaScript 的数字是双精度浮点数 (*),但按位运算符 (
<<
、>>
、&
、|
和~
) 是根据 32 位整数的运算来定义的。执行按位运算会将数字转换为 32 位有符号整型,丢失所有小数和高于 32 的位,然后再进行计算,然后转换回 Number。因此,进行没有实际效果的按位运算,例如右移 0 位
>>0
,是一种快速舍入数字并确保其位于 32 位 int 范围内的方法。另外,三重>>>
运算符在执行无符号运算后,将其计算结果转换为 Number 作为无符号整数,而不是其他运算符所做的有符号整数,因此可以用于将负数转换为 32 位二进制补码版本作为大数。使用>>>0
可确保您获得 0 到 0xFFFFFFFF 之间的整数。在这种情况下,这很有用,因为 ECMAScript 根据 32 位无符号整数定义数组索引。因此,如果您尝试以完全重复 ECMAScript 第五版标准所述的方式实现 array.filter,则可以将数字转换为 32 位无符号 int,如下所示。
实际上,这几乎没有实际需要,因为希望人们不会将
array.length
设置为0.5
、-1
、1e21
或'LEMONS'
。摘要:
(*:嗯,它们被定义为像浮点数一样。如果出于性能原因,某些 JavaScript 引擎实际上在可能的情况下使用了整数,我不会感到惊讶。但这将是您无法了解的实现细节充分利用任何优势。)
It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.
Although JavaScript's Numbers are double-precision floats(*), the bitwise operators (
<<
,>>
,&
,|
and~
) are defined in terms of operations on 32-bit integers. Doing a bitwise operation converts the number to a 32-bit signed int, losing any fractions and higher-place bits than 32, before doing the calculation and then converting back to Number.So doing a bitwise operation with no actual effect, like a rightward-shift of 0 bits
>>0
, is a quick way to round a number and ensure it is in the 32-bit int range. Additionally, the triple>>>
operator, after doing its unsigned operation, converts the results of its calculation to Number as an unsigned integer rather than the signed integer the others do, so it can be used to convert negatives to the 32-bit-two's-complement version as a large Number. Using>>>0
ensures you've got an integer between 0 and 0xFFFFFFFF.In this case this is useful because ECMAScript defines Array indexes in terms of 32 bit unsigned ints. So if you're trying to implement
array.filter
in a way that exactly duplicates what the ECMAScript Fifth Edition standard says, you would cast the number to 32-bit unsigned int like this.In reality there's little practical need for this as hopefully people aren't going to be setting
array.length
to0.5
,-1
,1e21
or'LEMONS'
.Summary:
(*: well, they're defined as behaving like floats. It wouldn't surprise me if some JavaScript engine actually used ints when it could, for performance reasons. But that would be an implementation detail you wouldn't get to take any advantage of.)
Mozilla 的所有array extra方法实现中都使用无符号右移运算符,以确保
length
属性是无符号32位整数嗯>。数组对象的
length
属性在描述中规格为:此运算符是实现它的最短方法,内部数组方法使用
ToUint32< /code>
操作,但该方法不可访问并且存在于用于实现目的的规范中。
Mozilla array extras 实现尝试成为 ECMAScript 5 兼容,请查看
Array.prototype.indexOf
方法的描述(第 15.4.4.14 节):如您所见,他们只是想重现
ToUint32 的行为
方法以符合 ES3 实现上的 ES5 规范,正如我之前所说, 无符号右移运算符是最简单的方法。The unsigned right shift operator is used in the all the array extra's method implementations of Mozilla, to ensure that the
length
property is a unsigned 32-bit integer.The
length
property of array objects is described in the specification as:This operator is the shortest way to achieve it, internally array methods use the
ToUint32
operation, but that method is not accessible and exist on the specification for implementation purposes.The Mozilla array extras implementations try to be ECMAScript 5 compliant, look at the description of the
Array.prototype.indexOf
method (§ 15.4.4.14):As you can see, they just want to reproduce the behavior of the
ToUint32
method to comply with the ES5 spec on an ES3 implementation, and as I said before, the unsigned right shift operator is the easiest way.这是无符号右移运算符。它与有符号右位移运算符之间的区别在于无符号右位移运算符(>>>)从左侧填充零,而有符号右位移运算符( >>)用符号位填充,从而在移位时保留数值的符号。
That is the unsigned right bit shift operator. The difference between this and the signed right bit shift operator, is that the unsigned right bit shift operator (>>>) fills with zeroes from the left, and the signed right bit shift operator (>>) fills with the sign bit, thus preserving the sign of the numerical value when shifted.
Driis 有充分解释了运算符是什么以及它的作用。以下是其背后的含义/使用原因:
将任意方向移动
0
确实会返回原始数字,并将null
转换为0
。看来您正在查看的示例代码正在使用this.length >>> 0
以确保len
是数字,即使未定义this.length
也是如此。对于许多人来说,按位运算并不清楚(Douglas Crockford/jslint 建议不要使用此类操作)。这并不意味着这样做是错误的,而是存在更有利和熟悉的方法来使代码更具可读性。确保
len
为0
的更明确方法是以下两种方法之一。或者
Driis has sufficiently explained what the operator is and what it does. Here's the meaning behind it/why it was used:
Shifting any direction by
0
does returns the original number and will castnull
to0
. It seems that the example code that you are looking at is usingthis.length >>> 0
to ensure thatlen
is numeric even ifthis.length
is not defined.For many people, bitwise operations are unclear (and Douglas Crockford/jslint suggests against using such things). It doesn't mean that its wrong to do, but more favorable and familiar methods exist to make code more readable. A more clear way to ensure that
len
is0
is either of the following two methods.or
>>>
是无符号右移运算符 (参见 JavaScript 1.5 规范第 76 页),而不是>>
,有符号右移运算符。>>>
会更改负数移位的结果,因为它移位时不保留符号位。其结果可以通过解释器的示例来理解:因此,这里可能要做的是获取长度,或者如果长度未定义或不是整数,则获取 0,如
“cabbage “
上面的例子。我认为在这种情况下,可以安全地假设this.length
永远不会是< 0 。尽管如此,我认为这个例子是一个令人讨厌的黑客,原因有两个:
使用负数时
<<<
的行为,一边- 在上面的示例中,效果可能不是预期的(或可能发生)。代码的意图并不明显,正如这个问题的存在所验证的那样。
最佳实践可能是使用更具可读性的东西,除非性能绝对至关重要:
>>>
is the unsigned right shift operator (see p. 76 of the JavaScript 1.5 specification), as opposed to the>>
, the signed right shift operator.>>>
changes the results of shifting negative numbers because it does not preserve the sign bit when shifting. The consequences of this is can be understood by example, from an interpretter:So what is probably intended to be done here is to get the length, or 0 if the length is undefined or not an integer, as per the
"cabbage"
example above. I think in this case it is safe to assume thatthis.length
will never be< 0
. Nevertheless, I would argue that this example is a nasty hack, for two reasons:The behavior of
<<<
when using negative numbers, a side-effect probably not intended (or likely to occur) in the example above.The intention of the code is not obvious, as the existence of this question verifies.
Best practice is probably to use something more readable unless performance is absolutely critical:
两个原因:
>>的结果是一个“积分”
>>
未定义>>>>> 0 = 0(因为 JS 会尝试将 LFS 强制为数字上下文,这也适用于“foo”>>> 0 等)
请记住,JS 中的数字有一个 double 的内部表示。
这只是基本输入长度的“快速”方式。
但是,-1>>> 0(哎呀,可能不是所需的长度!)
Two reasons:
The result of >>> is an "integral"
undefined >>> 0 = 0 (since JS will try and coerce the LFS to numeric context, this will work for "foo" >>> 0, etc. as well)
Remember that numbers in JS have an internal-representation of double.
It's just a "quick" way of basic input sanity for length.
However, -1 >>> 0 (oops, likely not a desired length!)
下面的示例 Java 代码很好地解释了:
输出如下:
Sample Java Code below explains well:
Output is the following: