前言
在开发过程中,我们常常使用数组的一些 api 相关操作,其中包含 forEach 、 filter 、 find 、 findIndex 、 map 、 some 、 every 、 reduce 、 reduceRight 等函数方法。今天,我们试试手写这些函数,实现数组这些函数方法。为了方便,直接在数组原型对象 prototype 上扩展。本文 Githab 已上传,往期文章已分类整理。正文正文参数说明

callbackFn 回调函数
thisArg 执行 callbackFn 时使用的 this 值
currentValue 数组中正在处理的元素
index 当前索引
array 源数组
accumulator 累加器
initialValue reduce reduceRight 第一次调用 callbackFn 函数时的第一个参数的值默认值
element 自己实现的 this 对象
callbackFn 回调函数thisArg 执行 callbackFn 时使用的 this 值currentValue 数组中正在处理的元素index 当前索引array 源数组accumulator 累加器initialValue reduce reduceRight 第一次调用 callbackFn 函数时的第一个参数的值默认值element 自己实现的 this 对象forEach 函数
语法: arr.forEach(callbackFn(currentValue [, index [, array]])[, thisArg]) arr.forEach(callbackFn(currentValue [, index [, array]])[, thisArg]) 方法功能: 对数组的每个元素执行一次给定的函数。返回:undefined。自定义函数:myForEach。
Array.prototype.myForEach = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
callbackFn.call(thisArg, element[index], index, element);
}
};

Array.prototype.myForEach = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
callbackFn.call(thisArg, element[index], index, element);
}
};
filter 函数
语法: var newArray = arr.filter(callbackFn(currentValue[, index[, array]])[, thisArg])var newArray = arr.filter(callbackFn(currentValue[, index[, array]])[, thisArg])方法功能: 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。返回:一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。自定义函数:myFilter。
Array.prototype.myFilter = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0,
result = [];
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) result.push(element[index]);
}
return result;
};

Array.prototype.myFilter = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0,
result = [];
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) result.push(element[index]);
}
return result;
};
find 函数
语法: arr.find(callbackFn[, thisArg])arr.find(callbackFn[, thisArg])方法功能: 返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。返回:数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。自定义函数:myFind。
Array.prototype.myFind = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) {

return element[index];
}
}
return
}

Array.prototype.myFind = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) {

return element[index];
}
}
return
}
findIndex 函数
语法: arr.findIndex(callbackFn[, thisArg])arr.findIndex(callbackFn[, thisArg])方法功能: 返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。返回:数组中通过提供测试函数的第一个元素的索引。否则,返回-1。自定义函数:myFindIndex。
Array.prototype.myFindIndex = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) return index;
}
return -1;
}

Array.prototype.myFindIndex = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) return index;
}
return -1;
}
fill函数
语法: arr.fill(value[, start[, end]])arr.fill(value[, start[, end]])方法功能: 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。返回:返回替换的值,原数组发生改变。自定义函数:myFill。
Array.prototype.myFill = function(value, start = 0, end) {
let element = this,
len = element && element.length || 0;
end = end || len;
let loopStart = start < 0 ? 0 : start, // 设置循环开始值
loopEnd = end >= len ? len : end; // 设置循环结束值

for (; loopStart < loopEnd; loopStart++) {
element[loopStart] = value;
}
return element;
}


Array.prototype.myFill = function(value, start = 0, end) {
let element = this,
len = element && element.length || 0;
end = end || len;
let loopStart = start < 0 ? 0 : start, // 设置循环开始值
loopEnd = end >= len ? len : end; // 设置循环结束值

for (; loopStart < loopEnd; loopStart++) {
element[loopStart] = value;
}
return element;
}

map 函数
语法: var new_array = arr.map(function callbackFn(currentValue[, index[, array]]) {// Return element for new_array }[, thisArg])var new_array = arr.map(function callbackFn(currentValue[, index[, array]]) {// Return element for new_array }[, thisArg])方法功能: 创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。返回:测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。 一个由原数组每个元素执行回调函数的结果组成的新数组。自定义函数:myMap。
Array.prototype.myMap = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0,
result = [];
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
result[index] = callbackFn.call(thisArg, element[index], index, element);
}
return result;
}

Array.prototype.myMap = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0,
result = [];
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
result[index] = callbackFn.call(thisArg, element[index], index, element);
}
return result;
}
some 函数
语法: arr.some(callbackFn(currentValue[, index[, array]])[, thisArg])arr.some(callbackFn(currentValue[, index[, array]])[, thisArg])方法功能: 测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。返回:数组中有至少一个元素通过回调函数的测试就会返回true;所有元素都没有通过回调函数的测试返回值才会为false。自定义函数:mySome。
Array.prototype.mySome = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) return true;
}
return false;
}

Array.prototype.mySome = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,
len = element && element.length || 0;
if (!thisArg) thisArg = element;
for (let index = 0; index < len; index++) {
if (callbackFn.call(thisArg, element[index], index, element)) return true;
}
return false;
}
every 函数
语法: arr.every(callbackFn(currentValue[, index[, array]])[, thisArg])arr.every(callbackFn(currentValue[, index[, array]])[, thisArg])方法功能 :测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。返回:如果回调函数的每一次返回都为 true 值,返回 true,否则返回 false。自定义函数:myEvery。
Array.prototype.myEvery = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element && element.length || 0;
if (!thisArg) thisArg = element;
for(let index = 0; index < len; index++) {

if (!callbackFn.call(thisArg, element[index], index, element)) return false;
}
return true;
}

Array.prototype.myEvery = function(callbackFn, thisArg) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element && element.length || 0;
if (!thisArg) thisArg = element;
for(let index = 0; index < len; index++) {

if (!callbackFn.call(thisArg, element[index], index, element)) return false;
}
return true;
}
reduce 函数
语法: arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])方法功能: 对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。返回:函数累计处理的结果。自定义函数:myReduce。
Array.prototype.myReduce = function(callbackFn, initialValue) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element.length || 0,

index = 0,

result;
if (arguments.length >= 2) {

result = arguments[1];
} else {

while (index < len && !(index in element)) index++;

if (index >= len) throw new TypeError('Reduce of empty array ' + 'with no initial value');

result = element[index++];
}

while (index < len) {

if (index in element) result = callbackFn(result, element[index], index, element);

index++;
}
return result;
}


Array.prototype.myReduce = function(callbackFn, initialValue) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element.length || 0,

index = 0,

result;
if (arguments.length >= 2) {

result = arguments[1];
} else {

while (index < len && !(index in element)) index++;

if (index >= len) throw new TypeError('Reduce of empty array ' + 'with no initial value');

result = element[index++];
}

while (index < len) {

if (index in element) result = callbackFn(result, element[index], index, element);

index++;
}
return result;
}

reduceRight 函数
语法: arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])方法功能: 接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。返回:执行之后的返回值。自定义函数:myReduceRight。
Array.prototype.myReduceRight = function(callbackFn, initialValue) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element.length || 0,

index = len - 1,

result;
if (arguments.length >= 2) {

result = arguments[1];
} else {

while (index >= 0 && !(index in element)) {

index--;

}

if (index < 0) {

throw new TypeError('reduceRight of empty array with no initial value');

}

result = element[index--];
}
for (; index >= 0; index--) {

if (index in element) {

result = callbackFn(result, element[index], index, element);

}
}
return result;
}

Array.prototype.myReduceRight = function(callbackFn, initialValue) {
if (typeof callbackFn !== 'function') throw ('callbackFn参数必须是函数');
let element = this,

len = element.length || 0,

index = len - 1,

result;
if (arguments.length >= 2) {

result = arguments[1];
} else {

while (index >= 0 && !(index in element)) {

index--;

}

if (index < 0) {

throw new TypeError('reduceRight of empty array with no initial value');

}

result = element[index--];
}
for (; index >= 0; index--) {

if (index in element) {

result = callbackFn(result, element[index], index, element);

}
}
return result;
}
最后