目录
- map()
- forEach()
- reduce()
- 三者区别
map()循环返回新数组
更加工程化的Polyfill代码:Array.prototype.map()
简化:
Array.prototype.map = function(callback){
//创建一个length值为原数组长度的新数组A
var A = new Array(this.length);
var O = Object(this); //强制转对象,为后续in操作符做准备
var k = 0;
//前测试循环语句,在循环前就会对出口条件求值
while(k{
return item+1;
}))
// [1,2,3,4]
知识点梳理:
- 在只知道数组要保存的项目数量情况下,可以使用
Array
构造函数创建数组,而该数值会自动变成length
属性的值 - 使用
while
前测试循环语句,适用于在循环次数不易预知的情况
map的第二个参数
arr.map(callback[, thisArg])
执行callback
函数时值被用作this
。
//传入的callback参数被赋值给了数组A对应的索引
A[ k ] = callback.call(thisArg, kValue, k);
forEach()遍历数组,并将元素传递给回调函数
更加工程化的Polyfill代码:Array.prototype.forEach()
简化:
Array.prototype.forEach= function(callback){
var k = 0;
while(k < this.length){
var kValue;
kValue = this[ k ];
this[ k ] = callback(kValue, k);
k++;
}
//这里是默认返回undefined
//return undefined
}
//eg:
var arr = [0,1,2,3];
console.log(a.forEach((item,index)=>{
return item+1;
})) // undefined
console.log(arr) // [0,1,2,3]
readuce()累加器
更加工程化的Polyfill代码:Array.prototype.reduce()
简化:
Array.prototype.reduce= function(callback){
//新建一个栈内存用于存储累加
var accumulator;
var k = 0;
//使用reduce时,回调函数callback共2个必填参数(accumulator和当前索引所在值)
//和1个非必填参数(原数组)
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < this.length && !(k in this)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= this.length) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = this[k++];
}
while(k{
return accumulator+currentValue
})) //6
案例:使用reduce和Promise实现事件列队[1]
设计一个简单的任务队列,要求分别在1,3,4秒后打印出”1“,”2“,”3“
new Queue()
.task(1000, () => {
console.log(1)
})
.task(2000, () => {
console.log(2)
})
.task(1000, () => {
console.log(3)
})
.start()
function Queue(){
this.event_list = []; //事件队列
this.task = function(duration, callback){
// 保证队列中所有事件都为Promise对象
var event_item = new Promise((resolve)=>{
setTimeout(()=>{
callback.bind(this)
resolve()
},duration)
})
event_list.push(event_item) //添加事件
// 返回当前实例实现链式调用
return this;
}
this.start = function(){
this.event_list.reduce(
//初始值, 或者计算结束后的返回值
//每次 reduce 返回的值都会作为下次 reduce 回调函数的第一个参数,
//直到队列循环完毕,因此可以进行累加计算。
(previousPromise, nextPromise) => previousPromise.then(() => nextPromise()),
Promise.resolve() //当前元素
)
}
}
map()与forEach()和reduce()区别:
方法 | map() | forEach() | reduce() |
---|---|---|---|
原数组 | 永远不变 | 永远不变 | 永远不变 |
原数组各索引上的值 | 永远不变 | 可能改变 | 永远不变 |
返回值 | 船新数组 | 永远undefined |
由callback() 决定 |
ps: 可能改变 指如果传入的callback会对item进行值改变并返回新值
其他
- 上述三种循环无法使用
return false
或者break
手动退出循环,除了抛出异常以外 - 数组(稀疏数组)中对于那些已经被删除或者从未被赋值的索引不会被执行
callback
var arr = [0, 1, 2]; arr[10] = 11; var arr2 = arr.map(function(x){ return x === undefined }); console.log(arr2); // []
参考
- [1] 为什么要使用reduce()来解决Promises执行顺序
- [2] 如何理解reduce()? - 翻译