JavaScript 之本身实现数组方法

1. concat

Array.prototype.concat = function(){
  const len = arguments.length
  let arr = []
  Object.assign(arr, this)  // 深拷贝
  for(let i = 0; i < len; i ++){
    if(arguments[i] instanceof Array){  // 是数组就拆解
      for(let j = 0, argArrLen = arguments[i].length; j < argArrLen; j ++){
        arr.push(arguments[i][j])
      }
    }else {  // 其余都直接push
      arr.push(arguments[i])
    }
  }
  return arr
}
复制代码

2. some

Array.prototype.some = function(fn){
  const len = this.length
  let result = false
  for(let i = 0; i < len; i ++){
    result = fn.call(undefined, this[i], i, this)
    if(result) return true
  }
  return false
}
复制代码

3. slice

Array.prototype.slice = function(fromIndex, toIndex){
  
  if(arguments.length === 0) return this  // 一个参数都不传
  let result = []
  const len = this.length

  fromIndex = (fromIndex + len) % len  // 将负索引转为对应正索引
  if(!toIndex) return [this[fromIndex]]  // 只传第一个参数
  toIndex = (toIndex < len) ? (toIndex + len) % len : len  // 判断toIndex是否超出数组最大索引
  for(let i = fromIndex; i < toIndex; i ++){
    result.push(this[i])
  }
  return result
}
复制代码

4. reduce

Array.prototype.reduce = function(fn){
  const len = this.length
  let result = this[0]  // 先把第一个元素放进去做为pre
  for(let i = 0; i < len - 1; i ++){  // i<len-1,这样取i+1恰好不会溢出
    result = fn.call(undefined, result, this[i+1])  // this不传,传入累加的结果(result)和下一位元素的值
  }
  return result
}
复制代码

5. map

Array.prototype.map = function(fn){
  const len = this.length
  let result = []
  for(let i = 0; i < len; i ++){
    result[i] = fn.call(undefined, this[i], i, this)  // 将回调的返回值存入新数组
  }
  return result
}
复制代码

6. join

Array.prototype.join = function(char){
  const len = this.length  // this为数组
  let result = this[0] || ''  // 取出第一位
  for(var i = 1; i < len; i ++){  // 循环累加,记得作空判断
    result += (char + (this[i] || ''))
  }
  return result
}
复制代码

7. indexOf

Array.prototype.indexOf = function(ele){
  if(!ele) return -1  // 没传直接返回-1
  const len = this.length
  for(let i = 0; i < len; i ++){
    if(this[i] === ele){  // 找到返回索引
      return i
    }
  }
  return -1  // 找不到
}
复制代码

8. forEach

Array.prototype.forEach = function(fn){
  const len = this.length
  for(let i = 0; i < len; i ++){
    if(i in this){  // 若是有第i项
      fn.call(undefined, this[i], i, this)  // 跟原生方法同样,this指向window。提供元素,索引,原数组三个参数
    }
  }
}
复制代码

9. filter

Array.prototype.filter = function(fn){
  const len = this.length
  let result = []
  for(let i = 0; i < len; i ++){
    if(i in this){  // 判断是否为空元素的索引
      fn.call(undefined, this[i], i, this) && (result.push(this[i]))
    }
  }
  return result
}
复制代码

10. every

Array.prototype.every = function(fn){
  const len = this.length
  let result = true
  for(let i = 0; i < len; i ++){
    result = fn.call(undefined, this[i], i, this)
    if(!result) return false  // 一旦发现result为false,返回false
  }
  return true  // 所有经过返回true
}
复制代码

... 未完待续数组

相关文章
相关标签/搜索