数组拓展
Array.prototype.forEach
forEach() 方法对数组的每个元素执行一次给定的函数。给定的函数有三个参数
- currentVal: 当前正在处理的元素
- index(可选): 当前元素索引
- self(可选): 数组本身 除了传给定函数外,还可以再传一个参数,这个参数将决定给定函数执行时内部 this 指向
forEach 的实现
Array.prototype.myForEach = function (callback, _this = window) {
if (Object.prototype.toString.call(this) !== "[object Array]") {
throw new Error("must be Array");
}
let arr = this;
for (let i = 0; i < arr.length; i++) {
callback.call(_this, arr[i], i, arr);
}
};
Array.prototype.filter
filter() 方法创建一个新数组, 其包含通过所提供函数筛选的所有元素。参数与 forEach() 相同
filter的实现
Array.prototype.myFilter = function (callback, _this = window) {
if (Object.prototype.toString.call(this) !== "[object Array]") {
throw new Error("must be Array");
}
let arr = this;
let result = [];
for (let i = 0; i < arr.length; i++) {
if (callback.call(_this, arr[i], i, arr)) {
result.push(arr[i]);
}
}
return result;
}
Array.prototype.map
map() 方法创建一个新数组,其结果是该数组中的每个元素调用一次提供的函数后的返回值。参数与 forEach() 相同
map的实现
Array.prototype.myMap = function (callback, _this = window) {
if (Object.prototype.toString.call(this) !== "[object Array]") {
throw new Error("must be Array");
}
let arr = this;
let result = [];
for (let i = 0; i < arr.length; i++) {
result.push(callback.call(_this, arr[i], i, arr));
}
return result;
}
Array.prototype.every
every() 方法测试数组内所有元素是否都能通过给定函数的测试,都通过返回 true ,只要有1个不通过返回 false 。参数与 forEach 相同
every的实现
Array.prototype.myEvery = function (callback, _this = window) {
if (Object.prototype.toString.call(this) !== "[object Array]") {
throw new Error("must be Array");
}
let arr = this;
for (let i = 0; i < arr.length; i++) {
// 有一个没通过直接返回false
if (!callback.call(_this, arr[i], i, arr)) {
return false;
}
}
// 全部通过返回true;
return true;
}
Array.prototype.some
some() 方法测试数组中是不是至少有1个元素通过了给定函数测试,有一个通过返回 true ,没有一个通过返回 false
some的实现
some 的实现与 every 类似,只需在循环中判断是否有通过测试的元素有就直接返回 true,循环结束仍未找到则返回 false
Array.prototype.reduce
reduce() 方法第一个参数是一个函数,该函数接收四个参数;第二个参数是 initiaValue
callback
accumulator: 累计器,它的值是上一次函数的返回值。currentValue: 数组正在处理的值index(可选): 数组当前元素索引self: 调用reduce方法的数组本身
initiaValue作为第一次传入函数的第一个参数的值,如果没有传入则为数组第一项的值,从数组第二项开始调用回调函数
reduce 方法在没有传入 initiaValue 使用时需要注意以下几个点
- 如果调用
reduce方法的数组长度为0时会报错Reduce of empty array with no initial value - 如果调用
reduce方法的数组长度为1时,reduce方法会直接返回数组第一项而不会去调用callback - 如果调用
reduce方法的数组长度大于1时,则会直接从数组第二项开始调用callback,函数第一个参数则为数组第一项的值
reduce的实现
Array.prototype.myReduce = function (callback, ...arg) {
if (Object.prototype.toString.call(this) !== "[object Array]") {
throw new Error("must be Array");
}
let arr = this;
let i = 0;
// 如果没有传入第二个参数且数组长度为0直接报错
// 长度为1则直接返回数组第一项
// 长度大于1直接从数组第二项开始循环
if (arg.length === 0) {
if (arr.length === 0) throw new Error("Reduce of empty array with no initial value");
else if (arr.length === 1) return arr[0];
else i = 1;
}
let result = arg[0];
for (i; i < arr.length; i++) {
result = callback(result, arr[i], i, arr);
}
return result;
}