Array.prototype.myMap = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};
Array.prototype.myReduce = function (callback, initialValue) {
let result = initialValue;
let start = 0;
if (initialValue === undefined) {
result = this[0];
start = 1;
}
for (let i = start; i < this.length; i++) {
result = callback(result, this[i], i, this);
}
return result;
};
Array.prototype.myFilter = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
result.push(this[i]);
}
}
return result;
};
Array.prototype.myFind = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return this[i];
}
}
return undefined;
};
Array.prototype.myFindIndex = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return i;
}
}
return -1;
};
Array.prototype.myEvery = function (callback) {
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
}
return true;
};
Array.prototype.mySome = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return true;
}
}
return false;
};
Array.prototype.myPush = function () {
for (let i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length;
};
Array.prototype.myUnshift = function () {
for (let i = 0; i < arguments.length; i++) {
for (let j = this.length; j > 0; j--) {
this[j] = this[j - 1];
}
this[0] = arguments[i];
}
return this.length;
};
Array.prototype.myPop = function () {
if (!this.length) return undefined;
const end = this[this.length - 1];
this[this.length - 1] = null;
this.length = this.length - 1;
return end;
};
Array.prototype.myShift = function () {
if (!this.length) return undefined;
const start = this[0];
for (let i = 1; i < this.length; i++) {
this[i - 1] = this[i];
}
this.length = this.length - 1;
return start;
};
结论
- 高阶函数其实都是对普通的for循环进行了一次封装。如果不在callback对原数组进行修改,那么高阶函数也是不会修改原数组的。
- 封装时主体逻辑容易编写,但需要注意一些小问题。比如push方法接受不定数量的参数、reduce方法的默认值可以不传等情况。
- push、unshift方法添加元素时,length会自动修改。而pop、shift是不会自动修改的,需手动设置length。