JavaScript进阶手写系列,手写13个数组方法的原理实现

文章目录

  • JavaScript进阶手写系列,手写数组方法的原理实现
    • 1、forEach
    • 2、map
    • 3、filter
    • 4、every
    • 5、some
    • 6、reduce
    • 7、findIndex
    • 8、find
    • 9、fill
    • 10、includes
    • 11、join
    • 12、flat
    • 13、splice

JavaScript进阶手写系列,手写数组方法的原理实现

1、forEach

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身
// forEach 
Array.prototype.myForEach = function(callback){
    for(let i=0;i<this.length;i++){
        callback(this[i],i,this)
    }
}

2、map

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

// map
Array.prototype.myMap = function(callback){
    let res = []
    for(let i=0;i<this.length;i++){
        res.push(callback(this[i],i,this))
    }
    return res
}

3、filter

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

//filter
Array.prototype.myFilter = function(callback){
    let res = []
    for(let i=0;i<this.length;i++){
        callback(this[i],i,this) && res.push(this[i])
    }
    return res
}

4、every

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

//every
Array.prototype.myEvery = function(callback){
    for(let i=0;i<this.length;i++){
        if(!callback(this[i],i,this)) return false  // 如果有一个不通过都返回false
    }
    return true
}

5、some

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

//some
Array.prototype.mySome = function(callback){
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this)) return true
    }
    return false
}

6、reduce

参数代表含义

  • pre:前一项
  • next:下一项
  • index:当前索引
  • arr:数组本身

reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

//reduce
Array.prototype.myReduce = function(callback,...initial){
    let start = 0,pre
    if(initial.length){
        pre = initial[0]
    }else{
        pre = this[0]
        start = 1
    }
    for(let i =start;i<this.length;i++){
        pre = callback(pre,this[i],i,this)
    }
    return pre
}

7、findIndex

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

//findeIndex
Array.prototype.myFindIndex = function(callback){
    for(let i =0;i<this.length;i++){
        if(callback(this[i],i,this)){
            return i
        }
    }
    return -1
}

8、find

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

//find
Array.prototype.myFind = function(callback){
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this)){
            return this[i]
        }
    }
    return undefined
}

9、fill

参数代表含义

  • item:遍历项
  • index:遍历项的索引
  • arr:数组本身

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

//fill
Array.prototype.myFill = function(value,start = 0,end){
    end = end || this.length
    for(let i =start;i<end;i++){
        this[i] = value
    }      
    return this
}

10、includes

用处:查找元素,查到返回true,反之返回false,可查找NaN

Array.prototype.myIncludes = function(value,start = 0){
    if(start<0) start = this.length + start
    const isNaN = Number.isNaN(value)
    for(let i=0;i<this.length;i++){
        if(this[i] === value || isNaN && Number.isNaN(this[i])){
            return true
        }
    }
    return false
}

11、join

用处:将数组用分隔符拼成字符串,分隔符默认为,

//join
Array.prototype.myJoin = function(s = ','){
    let str = ''
    for(let i =0;i<this.length;i++){
        if(i === 0) str = `${this[i]}`
        else str = `${str}${s}${this[i]}`
    }
    return str
}

12、flat

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

Array.prototype.myFlat = function(num = 1){
    let arr = this
    let i = 0
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr)
        i++
        if (i >= num) break
    }
    return arr
}

13、splice

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

难点

  • 截取长度和替换长度的比较,不同情况
Array.prototype.sx_splice = function (start, length, ...values) {
  if (length === 0) return []
  length = start + length > this.length - 1 ? this.length - start : length
  console.log(length)
  const res = [], tempArr = [...this]
  for (let i = start; i < start + values.length; i++) {
    this[i] = values[i - start]
  }
  this.length = start + values.length
  if (values.length < length) {
    const cha = length - values.length
    console.log(cha)
    for (let i = start + values.length; i < tempArr.length; i++) {
      this[i] = tempArr[i + cha]
    }
    this.length = this.length - cha 
  }
  if (values.length > length) {
    for (let i = start + length; i < tempArr.length; i++) {
      this.push(tempArr[i])
    }
  }
  for (let i = start; i < start + length; i++) {
    res.push(tempArr[i])
  }
  return res
}

你可能感兴趣的:(JS手写源码系列,javascript,面试,前端)