前端百題——數組中方法原理早知道

js的Array對象能夠調用不少方法,每個方法都有其特殊的用途,可是不少狀況下咱們僅僅會使用這麼高級方法,多於其實現過程知之甚少,本節就數組中的經常使用方法map、filter、reduce進行實現,幫助瞭解其原理。javascript

19.1 map

img

19.1.1 基礎

map() 方法建立一個新數組,其結果是該數組中的每一個元素是調用一次提供的函數後的返回值。html

  1. map方法的用法以下所示:
const new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // ……
}[, thisArg])
複製代碼
  1. 小試牛刀
const arr = [1, 2, 3, 4];

const newArr = arr.map(value => value * 3);

console.log(arr); // [ 1, 2, 3, 4 ] 原數組不變
console.log(newArr); // [ 3, 6, 9, 12 ]
複製代碼

19.1.2 實現

map作的事情很單純,就是處理每一個元素而後返回一個新的數組,下面就來看看怎樣實現本身的map函數。實現步驟以下所示:java

  1. 判斷輸入的第一個參數是否是函數
  2. 獲取須要處理的數組內容
  3. 新建一個新數組用於裝載新的內容
  4. 對數組中每一個值進行處理(注意改變this指向)
  5. 返回結果
Array.prototype.myMap = function(fn) {
    // 判斷輸入的第一個參數是否是函數
    if (typeof fn !== 'function') {
        throw new TypeError(fn + 'is not a function');
    }

    // 獲取須要處理的數組內容
    const arr = this;
    const len = arr.length;
    // 新建一個空數組用於裝載新的內容
    const temp = new Array(len);

    // 對數組中每一個值進行處理
    for (let i = 0; i < len; i++) {
        // 獲取第二個參數,改變this指向
        let result = fn.call(arguments[1], arr[i], i, arr);
        temp[i] = result;
    }
    // 返回新的結果
    return temp;
}

const arr = [1, 2, 3, 4];

const newArr = arr.myMap(value => value * 3);

console.log(arr); // [ 1, 2, 3, 4 ] 原數組不變
console.log(newArr); // [ 3, 6, 9, 12 ]

複製代碼

上述就是map的實現流程,而且通過驗證與原生的map方法的結果一致。git

19.2 filter

img

19.2.1 基礎

filter() 方法建立一個新數組, 其包含經過所提供函數實現的測試的全部元素。github

  1. filter方法的用法以下所示:
const newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
複製代碼
  1. 小試牛刀
const arr = [1, 2, 3, 4];

const newArr = arr.filter(value => value > 2);

console.log(arr); // [ 1, 2, 3, 4 ]

console.log(newArr); // [ 3, 4 ]
複製代碼

19.2.2 實現

filter函數作的事情就是過濾出符合條件的元素,對於filter的實現步驟和map的基本一致,不一樣之處在於其在數組中處理每一個值的時候稍有區別。數組

Array.prototype.myFilter = function (fn) {
    if (typeof fn !== 'function') {
        throw new TypeError(`${fn} is not a function`);
    }

    // 獲取該數組
    const arr = this;
    // 獲取該數組長度
    const len = this.length >>> 0;
    // 新建一個新的數組用於放置該內容
    const temp = [];

    // 對數組中每一個值進行處理
    for (let i = 0; i < len; i++) {
        // 處理時注意this指向
        const result = fn.call(arguments[1], arr[i], i, arr);
        result && temp.push(arr[i]);
    }

    return temp;
}

const arr = [1, 2, 3, 4];

const newArr = arr.myFilter(value => value > 2);

console.log(arr); // [ 1, 2, 3, 4 ]

console.log(newArr); // [ 3, 4 ]
複製代碼

19.3 reduce

img

19.3.1 基礎

reduce() 方法對數組中的每一個元素執行一個由您提供的reducer函數(升序執行),將其結果彙總爲單個返回值。函數

  1. reduce方法的用法以下所示:
const result = arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
複製代碼
  1. 小試牛刀
const arr = [1, 2, 3, 4];

const result = arr.reduce((accumulator, value) => accumulator + value);

console.log(result); // 10
複製代碼

19.3.2 實現

reduce爲數組中的每個元素依次執行callback函數,下面就來看看怎樣實現本身的filter函數。實現步驟以下所示:post

  1. 判斷輸入的第一個參數是否是函數
  2. 獲取須要處理的數組內容
  3. 獲取初始值
  4. 依次處理後續數組中的元素
  5. 返回累加器處理的結果
Array.prototype.myReduce = function(fn) {
    if (typeof fn !== 'function') {
        throw new TypeError(`${fn} is not a function`);
    }

    const arr = this;
    const len = arr.length >>> 0;
    let value;// 最終返回的值
    let k = 0;// 當前索引

    if (arguments.length >= 2) {
        value = arguments[1];
    } else {
        // 當數組爲稀疏數組時,判斷數組當前是否有元素,若是沒有索引加一
        while (k < len && !( k in arr)) {
            k++;
        }
        // 若是數組爲空且初始值不存在則報錯
        if (k >= len) {
            throw new TypeError('Reduce of empty array with no initial value');
        }
        value = arr[k++];
    }
    while (k < len) {
        if (k in arr) {
            value = fn(value, arr[k], k, arr);
        }
        k++;
    }

    return value;
}

const arr = [1, 2, 3, 4];

const result = arr.myReduce((accumulator, value) => accumulator + value);

console.log(result); // 10
複製代碼

1.若是以爲這篇文章還不錯,來個分享、點贊吧,讓更多的人也看到測試

若是你以爲這篇文章對你有點用的話,麻煩請給咱們的開源項目點點star:    http://github.crmeb.net/u/defu     不勝感激 !
來自 「開源世界 」 ,連接:    https://ym.baisou.ltd/post/735.html ,如需轉載,請註明出處,不然將追究法律責任。 ​​​​​​
 
相關文章
相關標籤/搜索