1. 为什么要手写代码?
我们在日常开发过程中,往往都是取出来直接用,从来不思考代码的底层实现逻辑,但当我开始研究一些底层的东西的时候,才开始理解了JavaScript每个方法和函数的底层实现思路,我认为这可以很好的提高我们的代码水平和逻辑思维。
2. 手写代码
2.1 forEach
2.1.1 基本使用
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
let arr = [1, 2, 3];
arr.forEach((item, index, arr) => {
console.log(item, index, arr);
});
2.1.2 手写实现
输出结果一致
Array.prototype.myForEach = function (callback) {
if (typeof callback !== 'function') {
throw new Error('参数必须是一个函数');
}
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
};
arr.myForEach(function (item, index, arr) {
console.log(item, index, arr);
});
2.2 map
2.2.1 基本使用
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
原数组不会发生改变
返回新的数组:在原数组的基础上都加1
let arr = [1, 2, 3, 4];
let newArr = arr.map((item, index, arr) => {
return item + 1;
});
console.log(newArr); // [2, 3, 4, 5]
console.log(arr); // 不会改变原数组 [1, 2, 3, 4]
2.2.2 手写实现
Array.prototype.myMap = function (callback) {
if (typeof callback !== 'function') {
throw new Error('参数必须是一个函数');
}
// 最终要返回的数组
let result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};
let newArr = arr.myMap((item, index, arr) => {
return item + 1;
});
console.log(newArr); // [2, 3, 4, 5]
console.log(arr); // 不会改变原数组 [1, 2, 3, 4]
2.3 filter
2.3.1 基本使用
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
filter() 不会改变原始数组。
返回数组中大于3的项
let arr = [1, 2, 3, 4, 5];
let newArr = arr.filter((item, index, arr) => {
return item > 2;
});
console.log(newArr); // [3,4,5]
console.log(arr); // [1,2,3,4,5]
2.3.2 手写实现
Array.prototype.myFilter = function (callback) {
if (typeof callback !== 'function') {
throw new Error('参数必须是一个函数');
}
let result = [];
for (let i = 0; i < this.length; i++) {
// 判断是否符合item > 2,符合则push到数组res里面返回
callback(this[i], i, this) && result.push(this[i]);
}
return result;
};
let newArr = arr.myFilter((item, index, arr) => {
return item > 2;
});
console.log(newArr); // [3,4,5]
console.log(arr); // [1,2,3,4,5]
2.4 every
2.4.1 基本使用
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
let arr = [1, 2, 3, 4, 5];
let flag = arr.every((item, index, arr) => {
return item > 4;
});
console.log(flag); // true
2.4.2 手写实现
Array.prototype.myEvery = function (callback) {
if (typeof callback !== 'function') {
throw new Error('参数必须是一个函数');
}
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
}
return true;
};
let flag = arr.every((item, index, arr) => {
return item > 4;
});
console.log(flag); // false
2.5 some
2.5.1 基本使用
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
2.5.2 手写实现
Array.prototype.mySome = function (callback) {
if (typeof callback !== 'function') {
throw new Error('参数必须是一个函数');
}
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
}
return true;
};
let flag = arr.mySome((item, index, arr) => {
return item > 3;
});
console.log(flag);
2.6 reduce
2.6.1 基本使用
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
语法:`
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
第一个参数total:必需。初始值, 或者计算结束后的返回值。
第二个参数currentValue:必需。当前元素
第三个参数currentIndex:可选。当前元素的索引
第四个参数arr:可选。当前元素所属的数组对象。
使用示例,实现数组元素的累加
let arr = [1, 2, 3, 4];
let sum = arr.reduce((tol, cur) => {
return (tol += cur);
}, 0);
console.log(sum); // 10
2.6.2 手写实现
Array.prototype.myReduce = function (callback, InitialValue) {
if (typeof callback !== 'function') {
throw new Error('传入第一个参数必须是函数');
}
const array = this;
// 如果没有传InitaialValue初始值时,初始值默认为数组的第一项即array[0]
let result = InitialValue || array[0];
for (let i = 0; i < array.length; i++) {
// 如果没有传第二个参数InitialValue初始值,当前数组第一项就不在进入循环
if (!InitialValue && i == 0) {
continue;
}
result = callback(result, array[i], i, this);
}
return result;
};
let result = arr.myReduce((tol, cur, index, arr) => {
return (tol += cur);
}, 0);
console.log(result); // 10
2.7 find
2.7.1 基本使用
find() 方法返回满足条件的数组的第一个元素的值。
let arr = [1, 2, 3];
let flag = arr.find((item, index, arr) => {
return item > 2;
});
console.log(flag); // 3
2.7.2 手写实现
Array.prototype.myFind = function (callback) {
if (typeof callback !== 'function') {
throw new Error('传入的参数必须是函数');
}
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return this[i];
}
}
return undefined;
};
let flag = arr.myFind((item, index, arr) => {
return item > 2;
});
console.log(flag);
2.8 findIndex
2.8.1 基本使用
findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
let arr = [1, 2, 3, 4];
let index1 = arr.findIndex((item, index, arr) => {
return item == 3;
});
console.log(index1);
2.8.2 手写代码
Array.prototype.myFindIndex = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return i;
}
}
return -1;
};
let index1 = arr.myFindIndex((item, index, arr) => {
return item == 3;
});
console.log(index1);
2.9 flatmap
2.9.1 基本使用
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,不改变原数组
使用map遍历时,操作完成后,如果遇到操作完的元素为数组,就进行一层的拍平
flatmap
faltmap(callback,thisArg)
第一个参数callback:可以传入 (item,i,arr) 执行
第二个参数thisArg:为执行callback时的this指向 thisArg文章来源:https://www.toymoban.com/news/detail-521291.html
代码示例:文章来源地址https://www.toymoban.com/news/detail-521291.html
let arr = [1, 2, 3, 4, 5];
let arr1 = arr.flatMap((item) => [item * 2]);
console.log(arr1); // [2, 4, 6, 8, 10]
console.log(arr); // [1, 2, 3, 4, 5] 原数组没有发生改变
let arr2 = arr.flatMap((item) => [[item * 2]]);
console.log(arr2); // 只能拍平一层 [[2], [4], [6], [8], [10]];
console.log(arr); // [1, 2, 3, 4, 5]
2.9.2 手写实现
Array.prototype.myFlatMap = function (callback, thisArg) {
let newArr = [];
for (let i = 0; i < this.length; i++) {
let res = callback.call(thisArg, arr[i], i, arr);
if (Array.isArray(res)) {
newArr.push(...res);
} else {
newArr.push(res);
}
}
return newArr;
};
let arr1 = arr.flatMap((item) => [item * 2]);
console.log(arr1); // [2, 4, 6, 8, 10]
let arr2 = arr.myFlatMap((item) => [[item * 2]]);
console.log(arr2); // 只能拍平一层 [[2], [4], [6], [8], [10]];
欢迎大家在讨论学习,感谢大家支持 |
到了这里,关于JavaScript 手写代码 第七期(重写数组方法三) 用于遍历的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!