数组减少Polyfill说明 [英] Array Reduce Polyfill Explanation

查看:72
本文介绍了数组减少Polyfill说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提前为冗长的帖子道歉。我想了解MDN提供的数组reduce polyfill。我无法理解polyfill中的一些行你能解释一下吗。下面是代码

Apologize in advance for lengthy post. I am trying to understand array reduce polyfill provided by MDN. I could not understand some lines in the polyfill can you explain it please. Below is the code

    if (!Array.prototype.reduce) {
      Object.defineProperty(Array.prototype, 'reduce', {
        value: function(callback /*, initialValue*/) {
          if (this === null) {
            throw new TypeError( 'Array.prototype.reduce ' + 
              'called on null or undefined' );
          }
          if (typeof callback !== 'function') {
            throw new TypeError( callback +
              ' is not a function');
          }

          // 1. Let O be ? ToObject(this value).
          var o = Object(this);

          // 2. Let len be ? ToLength(? Get(O, "length")).
          var len = o.length >>> 0; 

          // Steps 3, 4, 5, 6, 7      
          var k = 0; 
          var value;

          if (arguments.length >= 2) {
            value = arguments[1];
          } else {
            while (k < len && !(k in o)) {
              k++; 
            }

            // 3. If len is 0 and initialValue is not present,
            //    throw a TypeError exception.
            if (k >= len) {
              throw new TypeError( 'Reduce of empty array ' +
                'with no initial value' );
            }
            value = o[k++];
          }

          // 8. Repeat, while k < len
          while (k < len) {
            // a. Let Pk be ! ToString(k).
            // b. Let kPresent be ? HasProperty(O, Pk).
            // c. If kPresent is true, then
            //    i.  Let kValue be ? Get(O, Pk).
            //    ii. Let accumulator be ? Call(
            //          callbackfn, undefined,
            //          « accumulator, kValue, k, O »).
            if (k in o) {
              value = callback(value, o[k], k, o);
            }

            // d. Increase k by 1.      
            k++;
          }

          // 9. Return accumulator.
          return value;
        }
      });
    }

问题1:如果您看到第1步,

var o = Object(this);

通过将数组传递给polyfill方法,我检查了o和this的两个值。 o与此之间没有区别。它们都是数组(array.isarray在两者上都返回true),具有相同的数组值。为什么不在下面使用..?

I have checked both values of o and this, by passing an array to the polyfill method. There is no difference between o and this. They both are arrays(array.isarray returned true on both) with the same array value. Why not use below instead..?

var o = this;

问题2:第2步

var len = o.length >>> 0;

上面的行似乎右移o.length(32位)。但是,移位的位数是0.那么我们通过移位0位得到什么优势...为什么不在下面使用...?

Above line seems to right shift the o.length(32 bits). However no.of bits shifted is 0. So what advantage do we get by shifting 0 bits... Why not use below instead...?

var len = o.length;

问题3:第一个while条件在其他内部如下

Question 3: The first while condition inside else as below

 while (k < len && !(k in o)) {
    k++;
  }

最初k设置为0并且它似乎总是存在于o中。所以这个while循环条件永远不会成真。那么为什么我们需要这个while循环,如果它永远不会进入。

Initially k is set to 0 and it always seems to exist in o. So this while loop condition never gets to be true. So why do we need this while loop, if it never gets inside.

推荐答案

问题1:

确保在对象上调用 reduce ,因为可以通过函数调用reduce #call 函数#apply 甚至绑定函数#bind

To make sure reduce is called on an object as reduce could be called through Function#call, Function#apply or even bound Function#bind:

Array.prototype.reduce.call(undefined, function() {});

所以当访问 length等属性时,错误说无法访问属性****未定义的将不会被抛出。

So when accessing properties such as length, an error saying can't access property **** of undefined won't be thrown.

注意:上面的示例使用原生的 reduce ,如果没有提供对象,它实际上会抛出错误。

NOTE: the example above uses the native reduce which actually throws an error if not provided with an object.

问题2:

要始终将有效整数值设置为 length (即使它不存在):

To always have a valid integer value as length (even if it doesn't exist):

console.log(5 >>> 0);         // 5
console.log(5.5 >>> 0);       // 5
console.log("5" >>> 0);       // 5
console.log("hello" >>> 0);   // 0
console.log(undefined >>> 0); // 0

问题3:

处理稀疏数组:

var arr = [5, 6];
arr[7000000] = 7;

arr.reduce(function(acc, v, i) {
  console.log("index:", i);
}, 0);

它不会通过<的所有索引code> 0 到 7000000 ,只有真正存在的那些。

It won't go through all the indices from 0 to 7000000, only those that really exist.

这篇关于数组减少Polyfill说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆