JavaScript中的`>>>`运算符是什么?
我正在查看Array.prototype.map
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
if (!Array.prototype.map) { Array.prototype.map = function(callback/*, thisArg*/) { var T, A, k; if (this == null) { throw new TypeError('this is null or not defined'); } // 1. Let O be the result of calling ToObject passing the |this| // value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get internal // method of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If IsCallable(callback) is false, throw a TypeError exception. // See: http://es5.github.com/#x9.11 if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 1) { T = arguments[1]; } // 6. Let A be a new array created as if by the expression new Array(len) // where Array is the standard built-in constructor with that name and // len is the value of len. A = new Array(len); // 7. Let k be 0 k = 0; // 8. Repeat, while k < len while (k < len) { var kValue, mappedValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty internal // method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal // method of O with argument Pk. kValue = O[k]; // ii. Let mappedValue be the result of calling the Call internal // method of callback with T as the this value and argument // list containing kValue, k, and O. mappedValue = callback.call(T, kValue, k, O); // iii. Call the DefineOwnProperty internal method of A with arguments // Pk, Property Descriptor // { Value: mappedValue, // Writable: true, // Enumerable: true, // Configurable: true }, // and false. // In browsers that support Object.defineProperty, use the following: // Object.defineProperty(A, k, { // value: mappedValue, // writable: true, // enumerable: true, // configurable: true // }); // For best browser support, use the following: A[k] = mappedValue; } // d. Increase k by 1. k++; } // 9. return A return A; }; }
这是零填充右移运算符。
据Mozilla称,
“该操作符将第一个操作数向右移动指定的位数。 向右移位的多余位被丢弃。 零位从左侧移入。 符号位变为0,所以结果总是非负的。“
来源: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Unsigned_right_shift
真正的问题是,“polyfill为什么这样做?” 答案是代码试图模仿native .map()
方法的“普遍性”。 本机代码将使用任何看起来像数组的对象。 为此,代码检查是否存在一个.length
属性,如果有,则将其视为希望成为类似数组的对象的长度。 因为一个真正的数组总是有一个整数length
值,所以这个代码通过使用一个不做任何按位expression式来.length
任何引用整数的.length
属性。
还有其他无所作为的按位expression式, 通常也会起作用:
var len = ~~ O.length; var len = O.length | 0;
等等。 但是,在数组长度的特定情况下,位运算符(bitwise >>>
)的特殊之处在于它强制为无符号的 32位值。 如果你有一个数组超过20亿(加上一点点)的数组types的对象,它是有区别的。
所有的JavaScript按位运算符在执行它们的事情之前隐式地将浮点数操作数转换为32位整数,所以结果总是反映即使len
(expression式的结果)仍然是普通的JavaScript数字(双精度浮点)。