數組迭代方法polyfill

參考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

Array.prototype.forEach

  1. 描述:爲數組中的每個元素執行一次回調函數。
  2. 特點:
  • 不直接改變原數組
  • 返回 undefined
  • 不可鏈式調用
  • 不可中止或跳出循環,除非拋出異常
  1. 使用:
// currentValue 正在處理的當前元素
// index 正在處理的當前元素的索引
// array 數組本身
// thisArg 執行回調函數用的this,可選
arr.forEach(function (currentValue: any, index: number, array: []): void{
  //...do something
},thisArg:{})
  1. polyfill:
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(callback, thisArg) {
    var newThis;
    var index;

    // this就是調用arr.forEach的arr
    // 校驗arr,callback
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }

    if (arguments.length > 1) {
      newThis = thisArg;
    }

    var arr = Object(this);

    // >>>爲無符號移位,移位前將不是number類型的數據轉換成number,將number轉爲無符號的Uint32類型
    // Unit32類型轉換:不能轉爲number就爲0,非整數先轉爲整數,如果是正數返回正數,負數返回負數+2^32
    // >>>0保證len爲數字類型且爲正整數,缺省值爲0
    var len = arr.length >>> 0;

    index = 0;

    // 循環每個元素執行回調函數
    while (index < len) {
      var currentValue;

      if (index in arr) {
        currentValue = arr[index];

        // currentValue, index, arr是給回調函數的參數
        callback.call(newThis, currentValue, index, arr);
      }

      index++;
    }
  };
}

Array.prototype.map

  1. 描述:創建一個新數組,其結果是該數組中的每個元素都調用一個提供的函數後返回的結果。
  2. 特點:
  • 不直接修改原數組
  • 返回 callback 執行後的返回值組合的新數組
  • 不可中止或跳出循環
  • 可鏈式調用
  1. 使用:
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array
}[, thisArg])
  1. polyfill:
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {
    var newThis = thisArg || void 0,
      newArr,
      index;

    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    if (Object.prototype.toString.call(callback) != '[object Function]') {
      throw new TypeError(callback + ' is not a function');
    }

    var arr = Object(this);

    var len = arr.length >>> 0;

    newArr = new Array(len);

    index = 0;

    while (index < len) {
      var currentValue, mappedValue;

      if (index in arr) {
        currentValue = arr[index];

        mappedValue = callback.call(newThis, currentValue, index, arr);

        newArr[index] = mappedValue;
      }

      index++;
    }

    return newArr;
  };
}

Array.prototype.filter

  1. 描述:創建一個新數組, 其包含通過所提供函數實現的測試的所有元素。
  2. 特點:
  • 返回執行 callback 後返回 true 或者等價於 true 的元素組成的新數組
  • 不會直接改變原數組
  1. 使用:

var new_array = arr.filter(function callback(currentValue[, index[, array]]) {
 // Return element for new_array
}[, thisArg])
  1. polyfill:
if (!Array.prototype.filter) {
  Array.prototype.filter = function(callback, thisArg) {
    'use strict';
    if (!((typeof callback === 'Function' || typeof callback === 'function') && this)) {
      throw new TypeError();
    };

    var len = this.length >>> 0,
      newArr = new Array(len),
      arr = this,
      c = 0, // newArr的索引
      i = -1; // arr的索引,從-1開始++i
    if (!thisArg) {
      // 沒有傳入this,直接循環執行callback
      while (++i !== len) {
        if (i in arr) {
          // 如果callback執行返回true,則將當前條賦值給newArr
          if (callback(arr[i], i, arr)) {
            newArr[c++] = arr[i];
          }
        }
      }
    } else {
      while (++i !== len) {
        if (i in this) {
          if (callback.call(thisArg, arr[i], i, arr)) {
            newArr[c++] = arr[i];
          }
        }
      }
    }

    newArr.length = c;
    return newArr;
  };
}

注:可中止循環的有:簡單循環、for…of 循環、every()、some()、find()、findIndex(),數組的其他迭代方法 polyfill 可以根據以上方法的寫法進行改造。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章