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数字(双精度浮点)。