只要深刻理解了数组常用操作方法,这些手写题都不在话下了。
1. 实现数组的 filter
方法
/**
* 实现数组的 filter 方法
* @param {Function} callback (item: T, index: number, array: T[]) => boolean
* @returns T[]
*/
Array.prototype.myFilter = function (callback) {
let len = this.length;
let i = 0;
let result = [];
while (i < len) {
const bool = callback(this[i], i, this);
if (bool) {
result.push(this[i]);
}
i++;
}
return result;
}
2. 实现数组的 reduce
方法
/**
* 实现数组的 reduce 方法
* @param {Function} callback (pre: any, cur: T, index: number, array: T[]]) => any
* @param {any} initValue 如果没有提供,就使用数组的第一项作为初始值
* @returns any
*/
Array.prototype.myReduce = function (callback, initValue) {
let len = this.length;
let i = 0;
let accu = (typeof initValue != 'undefined') ? initValue : this[0];
while (i < len) {
accu = callback(accu, this[i], i, this);
i++;
}
return accu;
}
3. 使用 reduce
实现数组的 map
方法
/**
* 使用 reduce 实现数组的 map 方法 (实际上 map 方法确实是通过 reduce 实现)
* @param {Function} callback (item: T, index: number, array: T[]) => U
* @returns U[]
*/
Array.prototype.customMap = function (callback) {
return this.reduce((accu, cur, index, array) => {
const res = callback(cur, index, array);
accu.push(res);
return accu;
}, [])
}
进阶:使用 reduce
实现 Compose Function
function compose<T>(...middlewares: ((arg: T) => T)[]): (initValue: T) => T {
return (initValue) => {
return middlewares.reduce((accu, cur) => {
return cur(accu);
}, initValue)
}
}
function increment(n: number) {
return n + 1;
}
function double(n: number) {
return n * 2;
}
const middlewares = [
double,
double,
increment,
double
]
const composeFn = compose<number>(...middlewares);
composeFn(5); // 42