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
总结有错还请指出,谢谢