數組的forEach,map,filter,reduce,reduceRight,every,some方法

forEach

基本介紹

forEach按照升序爲數組中的每一項執行依此callback函數,那些已刪除或未初始化的項將被跳過(被顯式聲明爲undefined的一樣會被處理)數組

var a = [1,2, ,3], b = [1,2,undefined,3];
a.forEach(function(item){
    console.log(item);
});
//依次輸出1,2,3

b.forEach(function(item){
    console.log(item);
});
//依此輸出1,2,undefined,3
複製代碼

arr.forEach(callback[, thisArg]);promise

callback:爲數組中每一個元素執行的函數,且老是返回undefined
currentValue:正在處理的當前元素
(可選)index:正在處理的當前元素的索引
(可選)array:正在處理的數組
(可選)thisArg:執行callback時用做this的值bash

遍歷範圍

forEach遍歷的範圍在第一次調用callback前就會肯定函數

var a = [1,2];
a.forEach(function(current, i, arr){
    arr.push(current);
    console.log(current);
})
//依次打印1,2
複製代碼

本身作了如下的測試測試

var a = [1, 2,,3];
var count = 0;
a.forEach(function (current, i, arr) {
    count++;
})
console.log(count);//輸出3

var a = [1, 2,,3];
var count = 0;
a.forEach(function (current, i, arr) {
    arr[i+1] = current+1;
    count++;
})
console.log(count);//輸出4
複製代碼

上述的代碼跟以前總結的有點不太同樣啊?!forEach遍歷的範圍不是在第一次調用callback前就肯定的嗎?那那些沒有初始化的爲何還會執行呢?難道是我理解錯了?
我思考了一下,以爲forEach方法的執行是這樣的:ui

首先會根據數組的長度來確認循環的次數,這裏是4次
每次callback執行以前,都會去判斷當前處理的元素是否已定義,若是未定義,那麼不會執行callback直接跳到下一個處理的元素this

forEach遍歷的值是實時的,即若是已經存在的值被改變,則傳遞給callback的值是forEach遍歷到他們那一刻的值spa

var a = [1,2];
a.forEach(function(current, i, arr){
    arr[i+1] = current;
    console.log(current);
})
//依次打印1,1
複製代碼

以上的執行過程也是符合前面的總結的prototype

簡單實現

Array.prototype.fakeForEach = function(fn, thisArg){
    let arr = this;
    let len = arr.length;
    for(let i=0; i<len; i++){
        if(i in arr){//判斷當前的index是否已初始化
            fn.call(thisArg, arr[i], i, arr);
        }
    }
}
複製代碼

map

基本介紹

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

var a = [1,2,3];
var aa = map((current)=>{
    return current*current;
});
console.log([1,4,9]);
複製代碼

arr.map(callback[, thisArg]);同forEach

遍歷範圍同forEach

相關題目

['1','2','3'].map(parseInt);//結果是[1,NaN,NaN]   
複製代碼

parseInt(string, radix);//該函數返回以radix未基數解析的string整數
執行以上代碼時具體步驟以下

parseInt('1', 0);//默認以解析十進制返回1
parseInt('2', 1);//1進制中沒有2,返回NaN
parseInt('3', 2);//2進制中沒有3,返回NaN
返回[1,NaN,NaN]

簡單實現

Array.prototype.fakeMap = function(fn, thisArg){
    let arr = this;
    let len = arr.length;
    let newArr = new Array(len);
    for(let i=0; i<len; i++){
        if(i in arr){//判斷當前的index是否已初始化
            newArr[i] = fn.call(thisArg, arr[i], i, arr);
        }
    }
    return newArr;
}
複製代碼

reduce實現map

Array.prototype.fakeMap = function(fn, thisArg){
    let arr = this;
    let newArr = arr.reduce(function (newArr, current, i, arr){
        let o = fn.call(thisArg, current, i, arr);
        newArr.push(o);
        return newArr;
    },[])
    return newArr;
}
複製代碼

filter

基本介紹

filter方法建立一個新的數組,其包含執行callback後返回值爲true的全部元素

let arr = [1,2,3];
var newArr = arr.filter(function(item, i, arr){
    return item != 2;
});
newArr;//[1,3]
複製代碼

arr.filter(callback[, thisArg]);同forEach

遍歷範圍同forEach

簡單實現

Array.prototype.fakeFilter = function(fn, thisArg){
    let arr = this;
    let len = arr.length;
    let newArr = [];
    for(let i=0; i<len; i++){
        if(i in arr){//判斷當前的index是否已初始化
            if(fn.call(thisArg, arr[i], i, arr)){
                newArr.push(arr[i])
            }
        }
    }
    return newArr;
}
複製代碼

reduce

基本介紹

reduce方法按升序對數組中每一個元素執行callback,將accumulator賦值爲callback返回結果,返回最後的accumulatorreduce返回值

let arr = [1,2,3];
//對arr數組求和
let result = arr.reduce(function(accumulator, current, i, arr){
    return accumulator+current;
});
result;//6
複製代碼

arr.reduce(callback(accumulator, currentValue[ index [,array]]) [,initialValue]);

callback:爲數組中每一個元素執行的函數,且老是返回undefined
accumulator:累加器,它是上一次調用回調函數時返回的累積值
currentValue:正在處理的當前元素
(可選)index:正在處理的當前元素的索引
(可選)array:正在處理的數組
(可選)initialValue:做爲第一次執行callback時的值
返回值爲最後一次執行callback的返回值

遍歷範圍

大致上與forEach相同,遍歷流程不一樣之處以下

初始化執行次數n,有initialValue則賦值給accumulator,沒有則arr[0]賦值給accumulator
執行callback,將返回值賦值給accumulator × n
將最後一次執行callback的返回值返回

應用

按順序執行Promise

function runPromiseInOther(promiseArr, initialValue){
    return promiseArr.reduce(function(result, current){
            return result.then(current);
        }, Promise.resolve(initialValue)
    );
}
function p1(lastValue){
    return new Promise(function(resolve, reject){
        console.log(lastValue);
        resolve(lastValue * 10);
    })
}
function p2(lastValue){
    return new Promise(function(resolve, reject){
        console.log(lastValue);
        resolve(lastValue * 100)
    })
}
runPromiseInOther([p1,p2], 1)
    .then(console.log);
//依次輸出1,10,1000
複製代碼

簡單實現

arr.prototype.reduce(function(a, c, i, arr){return a+c;}, initialValue)
Array.prototype.fakeReduce = function(fn, initialValue){
    let arr = this;
    let len = arr.length;
    let i=0, result;
    if(arguments.length == 1){
        result = arr[0];
        i=1
    }else{
        result = initialValue;
    }
    for(; i<len; i++){
        if(i in arr){
            result = fn(result, arr[i], i, arr);
        }
    }
    return result;
}
複製代碼

every

基本介紹

every() 方法測試數組的全部元素是否都經過了指定函數的測試,若是測試callback有返回false則當即返回,後續的代碼不會被執行

let arr = [1,2,3];
console.log(
    arr.every(function(current){
        return current < 10;
    })
);//輸出true
複製代碼

arr.every(callback[, thisArg]);同forEach

遍歷範圍同forEach

簡單實現

Array.prototype.fakeEvery = function(fn, thisArg){
    let arr = this;
    let len = arr.length;
    for(let i=0; i<len; i++){
        if(i in arr){//判斷當前的index是否已初始化
            if(!fn.call(thisArg, arr[i], i, arr)){
                return false;
            }
        }
    }
    return true;
}
複製代碼

some

基本介紹

some()方法測試是否至少有一個元素經過由提供的函數實現的測試,若是測試callback有返回true則當即返回,後續的代碼不會被執行。

let arr = [1,2,3];
console.log(
    arr.some(function(current){
        return current < 2;
    })
);//輸出true
複製代碼

arr.some(callback[, thisArg]);同forEach

遍歷範圍同forEach

簡單實現

Array.prototype.fakeEvery = function(fn, thisArg){
    let arr = this;
    let len = arr.length;
    for(let i=0; i<len; i++){
        if(i in arr){//判斷當前的index是否已初始化
            if(fn.call(thisArg, arr[i], i, arr)){
                return true;
            }
        }
    }
    return false;
}
複製代碼

總結

  1. 不能使用break來跳出循環
  2. 都是按照升序來遍歷的
  3. 執行流程大體相同,具體看forEach的分析
  4. 實現的思路爲len初始化,for實現遍歷,in判斷是否已初始化,fn.call調用函數

參考材料:MDN
總結有錯還請指出,謝謝

相關文章
相關標籤/搜索