//reduce源码阅读
Array.prototype.myReduce = function (callback, initialValue) {
if (this === null) {//this指向的是Array,判断this是否为空
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {//判断callback是否为函数类型
throw new TypeError(callback + ' is not a function');
}
const O = Object(this);
console.log(O);
const lenValue = O.length;
console.log('lenValue: ' + lenValue);
const len = lenValue >>> 0;
console.log('len: ' + len);
if (len === 0 && !initialValue) {
throw new TypeError('the array contains no elements and initialValue is not provided');
}
let k = 0;
let accumulator;
// 分成两种情况来获取accumulator
// 有提供initialValue accumulator=initialValue
// 没有提供initialValue accumulator=数组的第一个有效元素
if (initialValue) {
accumulator = initialValue;
console.log('sss')
} else {//将数组的第一个元素赋值给accumulator
console.log('hhh')
let kPressent = false;
while (!kPressent && k < len) {
const pK = String(k);
console.log('pK: ' + pK);
kPressent = O.hasOwnProperty(pK);
if (kPressent) {
accumulator = O[pK];
};
k++;
console.log('k', k);
}
if (!kPressent) {
throw new TypeError('the array contains error elements');
}
}
// 当accumulator=initialValue时 k=0
// accumulator=数组的第一个有效元素时 k=1
while (k < len) {
if (k in O) {
// callback一般需要返回值
accumulator = callback(accumulator, O[k], k, O);
}
k++;
}
return accumulator;
}
let r = [1, 2, 3, 4].myReduce(function (prevValue, currentValue) {
return prevValue + currentValue;
});
console.log(r); // 28
// 数组中的reduce方法源码复写
// reduce原理:reduce方法主要是把数组遍历,然后把数组的每个元素传入回调函数中,回调函数(callback)怎么处理,就会的到什么样的效果。
Array.prototype._reduce = function (fn, initVal) {
let pre = initVal; //对初始值进行赋值
let i = 0; //数组的出事索引值
if (!pre) { //判断是否拥有初始值,如果有传初始值,下面遍历会从零开始,否则,遍历从1开始,下面遍历的第一个的pre值默认是数组的第一位元素
pre = this[0]; // 这里this指调用_reduce的数组,即 this指向调用函数的对象。
i = 1;
}
for (i; i < this.length; i++) {
pre = fn(pre, this[i], i); //遍历处理会调函数
}
return pre; //返回回调函数处理的最终结果,
}
// 计算一个数组中某个元素出现的次数;
let names = ['张三', '李四', '王五', '张三'];
let nameNum = names._reduce((pre, cur) => {
if (cur in pre) {
pre[cur]++;
} else {
pre[cur] = 1;
}
return pre;
}, {});
console.log(nameNum);
// 数组去重
let nameArr = names._reduce((pre, cur) => {
if (pre.indexOf(cur) == -1) {
pre.push(cur);
}
return pre;
}, []);
console.log(nameArr);
//将二维数组化为一维数组
let erweiArr = [
[1, 3.4, 5,],
[2, 4, 6],
[213],
[123, 123, 123]
];
let yiweiArr = erweiArr.reduce((pre, cur) => {
pre = pre.concat(cur);
return pre;
}, []);
console.log(yiweiArr);