JavaScript中的`>>>`运算符是什么?

时间:2017-11-22 01:12:36

标签: javascript node.js

我正在查看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;
  };
}

2 个答案:

答案 0 :(得分:2)

这是零填充右移操作符。

根据Mozilla的说法,

  

“此运算符将第一个操作数向右移位指定的位数。向右移位的多余位被丢弃。零位从左侧移入。符号位变为0,因此结果始终为非负数。“

来源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Unsigned_right_shift

答案 1 :(得分:1)

真正的问题是,“为什么填料会这样做?”答案是代码试图模仿原生.map()方法的“普世”性质。本机代码将提供任何看起来像数组的this对象。为此,代码检查是否存在.length属性,如果存在,则将其视为希望类似于数组的对象的长度。因为 real 数组总是具有整数length值,所以此代码通过使用do-nothing按位来强制对整数的任何.length引用的this属性表达

还有其他无用的按位表达式通常也可以正常工作:

var len = ~~ O.length;
var len = O.length | 0;

等等。但是,在数组长度的特定情况下,按位>>>运算符的特殊之处在于它强制执行无符号 32位值。如果你有一个类似数组的对象超过20亿(加上一点点)条目,那就有所不同。

所有JavaScript按位运算符在执行它们之前隐式地将浮点数操作数转换为32位整数,因此结果总是反映出即使len(表达式的结果)仍然是普通的JavaScript编号(双精度浮点)。