手写数组的常用方法----(如有写错或则不妥的地方评论区讲讲)
1.forEach() 方法对数组的每个元素执行一次给定的函数。
-
callback为数组中每个元素执行的函数,该函数接收一至三个参数:
-
currentValue数组中正在处理的当前元素。
-
index可选数组中正在处理的当前元素的索引。
-
array可选forEach()方法正在操作的数组。
-
-
thisArg可选可选参数。当执行回调函数
callback时,用作this的值。
const arr = [1,2,3,4,5]
arr.forEach((data,index,array)=>{
console.log(data) //1,2,3,4,5 数组元素
console.log(index) //0,1,2,3,4 数组元素索引
console.log(array) //[1,2,3,4,5] 原数组
})
我们现在开始手写这个数组方法
//首先当然要挂在数组原型上
//fn是forEach传入的回调函数也就是前面的callback,thisArgs是用作this指向
Array.prototype.myForEach = function (fn, thisArgs) {
//在这里判断下fn是不是函数
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;//这个是调用该方法的数组 例如:arr.forEach(()=>{}) 那么这个this就是数组arr
//下面开始遍历数组
for (let i = 0; i < self.length; i++) {
//通过call的改变fn的this指向再给上参数
fn.call(thisArgs, self[i], i, self); //self[i], i, self分别对应 数组元素、索引、原数组
}
};
有了forEach的写法,那么其他几种就很好理解了
2.map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
map和forEach大致相同,不同于map会返回一个新数组
-
callback生成新数组元素的函数,使用三个参数:
-
currentValuecallback数组中正在处理的当前元素。 -
index可选callback数组中正在处理的当前元素的索引。 -
array可选map方法调用的数组。
-
-
thisArg可选执行
callback函数时值被用作this。
返回值
一个由原数组每个元素执行回调函数的结果组成的新数组。
var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
return num * 2;
});
console.log(doubles) [2,8,18]
我们现在开始手写这个数组方法
Array.prototype.myMap = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
const array = [];//定义一个数组接收fn的返回值
for (let i = 0; i < self.length; i++) {
array[i] = fn.call(thisArgs, self[i], i, self);
}
return array;
};
3.filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
filter方法会对数组进行过滤,并返回过滤后的新数组
-
callback用来测试数组的每个元素的函数。返回
true表示该元素通过测试,保留该元素,false则不保留。它接受以下三个参数:-
element数组中当前正在处理的元素。
-
index可选正在处理的元素在数组中的索引。
-
array可选调用了
filter的数组本身。
-
-
thisArg可选执行
callback时,用于this的值。
返回值
一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。
let arr = [12, 5, 8, 130, 44]
const newArr = arr.filter(data=>{
return data > 10
});
console.log(newArr) //[12, 130, 44]
我们现在开始手写这个数组方法
Array.prototype.myFilter = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
const array = [];
for (let i = 0; i < self.length; i++) {
fn.call(thisArgs, self[i], i, self) && array.push(self[i]);
// fn.call(thisArgs, self[i], i, self) 会有一个返回值 例如:return data > 10
}
return array;
};
some()方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。 例如
const array = [1, 2, 3, 4, 5];
// checks whether an element is even
const even = (element) => element % 2 === 0;
console.log(array.some(even));
// expected output: true
我们现在开始手写这个数组方法
Array.prototype.mySome = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
for (let i = 0; i < self.length; i++) {
if (fn.call(thisArgs, self[i], i, self)) return true;
//这里的if如果理解不了,可以这样帮助理解
/**
例如:array.mySome((element) =>{
return element % 2 === 0
})
if( element % 2 === 0 ) return true
*/
}
return false;
};
有了some的写法借鉴,下面的三个every、find、findIndex就很好理解了
下面三个我就直接给写法,概念可以看看MDN https://developer.mozilla.org/zh-CN/
5.every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
Array.prototype.myEvery = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
for (let i = 0; i < self.length; i++) {
if (!fn.call(thisArgs, self[i], i, self)) return false;
}
return true;
};
find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。
Array.prototype.myFind = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
for (let i = 0; i < self.length; i++) {
if (fn.call(thisArgs, self[i], i, self)) return self[i];
}
return undefined;
};
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
Array.prototype.myFindIndex = function (fn, thisArgs) {
if (typeof fn !== "function") {
throw "fn is not function";
}
let self = this;
for (let i = 0; i < self.length; i++) {
if (fn.call(thisArgs, self[i], i, self)) return i;
}
return -1;
};