js-手寫數組經常使用方法的實現

前言

數組的api比較多,下面主要列舉一些經常使用的api實現,主要是參考MDN上Array的Polyfill來實現的。web

MDN連接:developer.mozilla.org/zh-CN/docs/…api

forEach

forEach主要用於遍歷數組數組

/** * @description: forEach簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
Array.prototype._forEach = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1 // 索引
  const { length: len } = this // 數組長度
  while (++index !== len) {
    if (index in this) { // 數組下標非連續的狀況
      callback.call(thisArg, this[index], index, this)
    }
  }
}
複製代碼

filter

filter主要用於過濾數組markdown

/** * @description: filter簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
 Array.prototype._filter = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1, newIdx = 0 // 索引、返回新數組索引
  const { length: len } = this // 原數組長度
  const result = [] // 返回的新數組
  while (++index !== len) {
    if (index in this) { // 數組下標非連續的狀況
      if (callback.call(thisArg, this[index], index, this)) {
        result[newIdx++] = this[index]
      }
    }
  }
  return result
}
複製代碼

map

map中callback必需要有返回值,結果返回一個由callback返回值組成的新數組。app

/** * @description: map簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 * @return {Array} 返回callback返回值組成的新數組 */
 Array.prototype._map = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1 // 索引
  const { length: len } = this // 數組長度
  const result = [] // 返回的新數組
  while (++index !== len) {
    if (index in this) { // 數組下標非連續的狀況
      result[index] = callback.call(thisArg, this[index], index, this)
    }
  }
  return result
}
複製代碼

reduce

reduce相對比較複雜,須要判斷是否傳入初始值,而且每次循環的結果要傳遞到下一次循環當中。函數

/** * @description: reduce簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
Array.prototype._reduce = function (...args) {
  const callback = args[0] // 回調函數
  const { length: len } = this // 數組長度
  const { length: argLen } = args // 參數長度
  let index = -1 // 數組下標
  let result

  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  
  // 存在第二個參數,做爲函數的初始值initialValue
  if (argLen >= 2) {
    result = args[1]
  } else {
    // 找到數組第一項的下標
    while (index < len && !(index in this)) {
      index++
    }
    // 數組爲空而且沒有初始值的狀況
    if (index >= len) {
      throw new TypeError('Reduce of empty array with no initial value')
    }
    result = arr[index++]
  }
  while (++index !== len) {
    if (index in this) {
      // 將每次返回的結果傳入下一次循環
      result = callback(result, this[index], index, this)
    }
  }
  return result
}
複製代碼

find

find找到符合條件的項就返回,沒有找到返回undefined。oop

/** * @description: find簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
 Array.prototype._find = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1 // 索引
  const { length: len } = this // 原數組長度
  while (++index !== len) {
    if (callback.call(thisArg, this[index], index, this)) {
      return this[index] // 若是是findIndex則return index
    }
  }
}
複製代碼

some

some和find除了返回值實現步驟同樣ui

/** * @description: some簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
 Array.prototype._some = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1 // 索引
  const { length: len } = this // 原數組長度
  while (++index !== len) {
    if (callback.call(thisArg, this[index], index, this)) {
      return true
    }
  }
  return false
}
複製代碼

every

every和some也差很少,只有所有符合條件才返回true,有一項不符合就返回false。this

/** * @description: every簡單實現 * @param {Function} callback 回調函數 函數中接受(當前遍歷的元素,當前遍歷索引,當前遍歷的數組)三個參數 * @param {Any} thisArg 傳入能夠改變callback的this指向 */
 Array.prototype._every = function (callback, thisArg) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + ' is not a function')
  }
  let index = -1 // 索引
  const { length: len } = this // 原數組長度
  while (++index !== len) {
    if (!callback.call(thisArg, this[index], index, this)) {
      return false
    }
  }
  return true
}
複製代碼

先寫這麼多,後面再補充其餘的。spa

相關文章
相關標籤/搜索