(十三) 实现数组新增方法

  • 实现的核心思路就是利用这些方法的特性: 比如有没有返回值, 返回值是什么
  • 对回调函数的理解

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);
posted @ 2021-08-02 22:48  只猫  阅读(132)  评论(0编辑  收藏  举报