[英]Hack to convert javascript number to UInt32
编辑:此问题已过期,因为Polyfill示例已更新。 我在这里留下这个问题仅供参考。 阅读关于按位移位运算符的有用信息的正确答案。
题:
在Mozilla Array.prototype.indexOf页面的Polyfill示例中的第7行,他们对此进行评论:
var length = this.length >>> 0; // Hack to convert object.length to a UInt32
但Mozilla上的按位移位规范明确指出运算符返回与左操作数相同类型的值:
移位运算符将其操作数转换为32位整数,并返回与左操作数相同类型的结果。
所以不应该长度接收标准的64位浮点值? 或者有人能指出我黑客入手的地方?
ECMAScript规范声明该值在http://www.ecma-international.org/ecma-262/5.1/#sec-11.7的步骤5和8中转换为UInt32:
11.7.3无符号右移运算符(>>>)
对左操作数执行零填充按位右移操作,操作数由右操作数指定。
生产
ShiftExpression : ShiftExpression >>> AdditiveExpression
的计算方法如下:
- 让
lref
成为评估ShiftExpression
的结果。- 设
lval
为GetValue(lref)
。- 让
rref
成为评估AdditiveExpression
的结果。- 设
rval
为GetValue(rref)
。- 让
lnum
成为ToUint32(lval)
。- 让
rnum
成为ToUint32(rval)
。- 设
shiftCount
是屏蔽除rnum
的最低有效5位之外的所有位的rnum
,即计算rnum & 0x1F
。- 返回通过
shiftCount
位执行lnum
的零填充右移的结果。 空位用零填充。 结果是无符号的32位整数 。
实际上,结果被转换回一个数字,即64位精度浮点数。 但是,在转换回来之前,两个操作数都转换为UInt32
,然后执行右移操作。 这在ECMAScript中有详细说明: http : //www.ecma-international.org/ecma-262/5.1/#sec-11.7.3
因此, length >>> 0
的净结果是因为>>> 0
本身是无操作,将length
转换为UInt32
然后再转换为双UInt32
。 到底有什么好处呢? 它会强制精度损失,并有效地强制值为1),整数和2)在[0,2 ^ 32-1]范围内。 例如,如果它是-1,它将变为2 ^ 32-1 == 4294967295。如果是,3.6,它将变为3。
如果您运行此测试,Math.floor将执行相同的操作。 如果您想在一个月左右的时间内了解自己的代码,就应该避免这些黑客攻击。
var a=3.6, b = a >>> 0;
console.log(b);
console.log(Math.floor(a));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.