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
}
複製代碼

... 未完待續數組

相關文章
相關標籤/搜索