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
方法建立一個新的數組,其結果是該數組中每個元素都調用一個提供的函數後返回的結果。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
方法建立一個新的數組,其包含執行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
方法按升序對數組中每一個元素執行callback
,將accumulator
賦值爲callback
返回結果,返回最後的accumulator
爲reduce
返回值
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()
方法測試數組的全部元素是否都經過了指定函數的測試,若是測試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()
方法測試是否至少有一個元素經過由提供的函數實現的測試,若是測試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;
}
複製代碼
參考材料:MDN
總結有錯還請指出,謝謝