(十三) 实现数组新增方法
- 实现的核心思路就是利用这些方法的特性: 比如有没有返回值, 返回值是什么
- 对回调函数的理解
1. 实现forEach
Array.prototype.myForEach = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
for (let i = 0, l = this.length; i < l; i++) {
fn(this[i], i, this)
}
}
// 测试
let arr = ['a', 'b', 'c', 'd', 'e']
arr.myForEach((item, index) => {
console.log(item, index);
})
2. 实现map
map的特性: 返回一个新数组
Array.prototype.myMap = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
let newArr = []
for (let i = 0, l = this.length; i < l; i++) {
newArr.push(fn(this[i], i, this))
}
return newArr
}
// 测试
let arr = [1, 2, 3, 4, 5]
let newArr = arr.myMap((item) => {
return item * item
})
console.log(newArr);
3. 实现filter
filter
特性: 返回一个新数组, 数组元素是满足条件的原数组的成员
Array.prototype.myFilter = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
let newArr = []
for (let i = 0, l = this.length; i < l; i++) {
if (fn(this[i], i, this)) {
newArr.push(this[i])
}
}
return newArr
}
// 测试
let arr = [1, 2, 3, 4, 5]
let newArr = arr.myFilter((item) => {
return item > 3
})
console.log(newArr);
4. 实现find
find
的特性: 返回第一个符合条件的数组成员
Array.prototype.myFind = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
for (let i = 0, l = this.length; i < l; i++) {
if (fn(this[i], i, this)) {
return this[i]
}
}
return newArr
}
// 测试
let arr = [1, 2, 3, 4, 5]
let item = arr.myFind((item) => {
return item > 2
})
console.log(item);
5. 实现every
every
特性:
- 返回一个布尔值
- 数组成员都满足条件. 返回true, 有一个不满足条件, 返回false
Array.prototype.myEvery = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
for (let i = 0, l = this.length; i < l; i++) {
if (!fn(this[i], i, this)) {
return false
}
}
return true
}
// 测试
let arr = [1, 2, 3, 4, 5]
let res = arr.myEvery((item) => {
// return item >= 1
return item >= 2
})
console.log(res);
6. 实现some
some
的特性与 every
相反
- 返回一个布尔值
- 有一个数组元素满足条件, 就返回true, 所有都不满足, 才返回false
Array.prototype.mySome = function (fn) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
for (let i = 0, l = this.length; i < l; i++) {
if (fn(this[i], i, this)) {
return true
}
}
return false
}
// 测试
let arr = [1, 2, 3, 4, 5]
let res = arr.mySome((item) => {
return item >= 2
})
console.log(res);
7. 实现reduce *
reduce
的特性:
-
两个参数, 一个是回调函数, 一个是累加器
-
累加器参数不传的话, 默认为数组第一项
-
最终的返回值是累加器的结果
let arr = [1, 2, 3, 4, 5]
Array.prototype.myReduce = function (fn, value) {
if (Object.prototype.toString.call(fn) !== '[object Function]') {
throw new Error(`${fn} is not a function`)
}
// 要根据有没有传入acc来进行初始化
// 没有传入, acc默认值是数组第一项, 遍历开始从第二项开始]
// 利用arguments长度来判断传入
let arr = this
let initIndex = arguments.length === 1 ? 1 : 0
let acc = arguments.length === 1 ? arr[0] : value
for (let i = initIndex, l = arr.length; i < l; i++) {
acc = fn(acc, arr[i], i, arr)
}
return acc
}
let res = arr.myReduce((acc, cur) => {
return acc + cur
}, 2)
console.log(res);
仅记录自己的学习总结,如有错误,还请评论指正~