js手寫數組Api--模擬實現常見數組Api

數組的API常常用,可是api的內部實現還沒研究過,因而就研究學習了下。

原文地址: http://www.javashuo.com/article/p-wgqkngch-bg.htmlhtml

數組的API的具體使用方看這裏 API詳細用法
本文記錄了數組中的 every,filter, find , indexOf, forEach, from, includes, isArray, map, reduce,slice,splice, sort這些個API的實現,若有不當,歡迎指出。api

Every

定義和用法:

every() 方法用於檢測數組全部元素是否都符合指定條件(經過函數提供)。
every() 方法使用指定函數檢測數組中的全部元素:
若是數組中檢測到有一個元素不知足,則整個表達式返回 false ,且剩餘的元素不會再進行檢測。
若是全部元素都知足條件,則返回 true。
注意: every() 對空數組檢測 返回 true。
注意: every() 不會改變原始數組。數組

語法

array.every(function(currentValue,index,arr), thisValue)函數

代碼實現:
Array.prototype._every = function (fn, thisValue) {
    let arr = thisValue || this // thisValue 有值 就以thisValue 爲準
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    // 空數組 返回 true
    if (!arr.length) {
      return true
    }
    for (let i = 0; i < arr.length; i++) {
      if (!fn.call(this, arr[i], i, arr)) {
        return false
      }
    }
    return true
}

function checkAdult(item) {
  return item >= 11
}

let arr = [32, 33, 16, 40]
let result = arr._every(checkAdult)
console.log(result) // true

Filter

定義和用法:

filter() 方法建立一個新的數組,新數組中的元素是經過檢查指定數組中符合條件的全部元素。
注意: filter() 不會對空數組進行檢測。
注意: filter() 不會改變原始數組。學習

語法

array.filter(function(currentValue,index,arr), thisValue)測試

代碼實現
Array.prototype._filter = function (fn, thisValue) {
    let arr = thisValue || this
    let result = []
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    if (!arr.length) { // 空數組不處理 直接返回空數組
        return []
    }
    for (let i = 0; i < arr.length; i++) {
      if(fn.call(arr, arr[i], i, arr)) {
        result.push(arr[i])
      }
    }
    return result
}

let arr = [4, 9, 16, 25];
let result = arr._filter((item) => {
    return item > 10
})
console.log(result) // [16, 25]

Find

定義和用法

find() 方法返回經過測試(函數內判斷)的數組的第一個元素的值。
find() 方法爲數組中的每一個元素都調用一次函數執行:
當數組中的元素在測試條件時返回 true 時, find() 返回符合條件的元素,以後的值不會再調用執行函數。
若是沒有符合條件的元素返回 undefined
注意: find() 對於空數組,函數是不會執行的。
注意: find() 並無改變數組的原始值。ui

語法

array.find(function(currentValue, index, arr),thisValue)this

代碼實現
Array.prototype._find = function (fn, thisValue) {
  let arr = thisValue || this
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  if (!this.length) { // 空數組返回 undefined
    return undefined
  }
  for (let i = 0; i < arr.length; i++) {
    let result = fn.call(arr, arr[i], i, arr)
    if (result) {
      return arr[i]
    }
  }
  return undefined
}

let arr = [3, 10, 18, 20]
function checkAdult(age) {
  return age > 11
}
let result = arr._find(checkAdult)
console.log(result) // 18

IndexOf

定義和用法

indexOf() 方法可返回數組中某個指定的元素位置。
該方法將從頭至尾地檢索數組,看它是否含有對應的元素。開始檢索的位置在數組 start 處或數組的開頭(沒有指定 start 參數時)。若是找到一個 item,則返回 item 的第一次出現的位置。開始位置的索引爲 0。
若是在數組中沒找到指定元素則返回 -1。spa

語法

array.indexOf(item,start)prototype

代碼實現
Array.prototype._indexOf = function (item, start = 0) {
  let arr = this
  for (let i = start; i < arr.length; i++) {
    if (item === arr[i]) {
      return i
    }
  }
  return -1
}

let arr = ["Banana","Orange","Apple","Mango","Banana","Orange","Apple"];
let result = arr._indexOf("Apple", 4)
console.log(result) // 6

ForEach

定義和用法

forEach() 方法用於調用數組的每一個元素,並將元素傳遞給回調函數。
注意: forEach() 對於空數組是不會執行回調函數的。

語法

array.forEach(function(currentValue, index, arr), thisValue)

代碼實現
Array.prototype._forEach = function (fn, thisValue) {
    let arr = thisValue || this
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    for (let i = 0; i < arr.length; i++) {
      fn.call(arr, arr[i], i, arr);
    }
}

let arr = [4, 9, 16, 25];
arr._forEach((item, i, arr) => {
    console.log('item:' + item + '  i: ' + i)
})

From

定義和用法

from() 方法用於經過擁有 length 屬性的對象或可迭代的對象來返回一個數組。
若是對象是數組返回 true,不然返回 false。

語法

Array.from(object, mapFunction, thisValue)

代碼實現
Array.prototype._from = function (object, mapFunction, thisValue) {
    let obj = thisValue || this
    let result = []
    // 沒有length屬性 或者 length 爲0的 直接返回空數組
    if (!object.length) {
        return result
    }
    if (typeof object === 'string') {
        result = object.split('')
    } else {
        object.forEach(item => result.push(item))
    }
    if (typeof mapFunction !== 'function') {
      throw new TypeError(mapFunction + ' is not a function');
    }
    return result.map(mapFunction, thisValue)
}

let r1 = Array.prototype._from([1, 2, 3], x => x * 10)
console.log(r1) // [10, 20, 30, 40]
let r2 = Array.prototype._from('1234', x => x * 10)
console.log(r2) // [10, 20, 30]

Includes

定義和用法

includes() 方法用來判斷一個數組是否包含一個指定的值,若是是返回 true,不然false。

語法

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

代碼實現
Array.prototype._includes = function (searchElement, fromIndex = 0) {
  let arr = this
  if (fromIndex >= arr.length || !arr.length){
    return false
  }
  for (let i = fromIndex; i < arr.length; i++) {
    if (arr[i] === searchElement) {
      return true
    }
  }
  return false
}

let arr = ['a', 'b', 'c', 'd']

let result = arr._includes('b')
console.log(result) // true

isArray

定義和用法

isArray() 方法用於判斷一個對象是否爲數組。
若是對象是數組返回 true,不然返回 false。

語法

Array.isArray(obj)

代碼實現
Array.prototype._isArray = function (item) {
  // 只是判斷數組用這個就夠了
  // 判斷數據類型最全面,最準確的方式是用 Object.prototype.toString.call(1)
  if(item.__proto__.constructor === Array) {
    return true
  } else {
    return false
  }
}

let arr = [1, 2, 3, 4]
console.log(Array.prototype._isArray(arr))  // true

Map

定義和用法

map() 方法返回一個新數組,數組中的元素爲原始數組元素調用函數處理後的值。
map() 方法按照原始數組元素順序依次處理元素。
注意: map() 不會對空數組進行檢測。
注意: map() 不會改變原始數組。

語法

array.map(function(currentValue,index,arr), thisValue)

代碼實現
Array.prototype._map = function (fn, thisValue) {
  let arr = thisValue || this
  let result = []
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  for (let i = 0; i < arr.length; i++) {
    let r = fn.call(arr, arr[i], i, arr)
    result.push(r)
  }
  return result
}

let arr = [4, 9, 16, 25];
let result = arr._map((item) => {
    return item * 2
})

console.log(result) //[8, 18, 32, 50]
console.log(arr) //[4, 9, 16, 25]

Reduce

定義和用法

reduce() 方法接收一個函數做爲累加器,數組中的每一個值(從左到右)開始縮減,最終計算爲一個值。
reduce() 能夠做爲一個高階函數,用於函數的 compose。
注意: reduce() 對於空數組是不會執行回調函數的。

語法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

代碼實現
Array.prototype._reduce = function (fn, initialValue) {
  let arr = this
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  if (!arr.length) {
    throw new TypeError('數組不能爲空');
  }
  let result = initialValue || 0
  for (let i = 0; i < arr.length; i++) {
    result = fn.call(arr, result, arr[i], i, arr)
  }
  return result
}

let arr = [1, 2, 3, 4];
function getSum(total, currentValue, currentIndex, arr) {
  return total + currentValue
}
let result = arr._reduce(getSum, 2)
console.log(result) // 12

Slice

定義和用法

slice() 方法可從已有的數組中返回選定的元素。
slice()方法可提取字符串的某個部分,並以新的字符串返回被提取的部分。
注意: slice() 方法不會改變原始數組。

語法

array.slice(start, end)

代碼實現
Array.prototype._slice = function (start, end) {
    let result = []
  for (let i = start; i < start + end; i++){
    result.push(this[i])
  }
  return result
}

let arr = ["Banana", "Orange", "Lemon", "Apple", "Mango"]
let result = arr._slice(1, 3)

console.log(result) // ["Orange", "Lemon", "Apple"]
console.log(arr) // ["Banana", "Orange", "Lemon", "Apple", "Mango"]

Splice

定義和用法

splice() 方法用於添加或刪除數組中的元素。
注意:這種方法會改變原始數組。

返回值

若是僅刪除一個元素,則返回一個元素的數組。 若是未刪除任何元素,則返回空數組。

語法

array.splice(index,howmany,item1,.....,itemX)

代碼實現
Array.prototype._splice = function (index, howmany = 0) {
  let arr = this
  let left = arr.slice(0, index) // 截取左邊的數組
  let right = arr.slice(index + howmany, arr.length) // 截取右邊的數組
  let subArr = Array.prototype.slice.call(arguments, 2) // 截取參數裏面須要添加的數組
  let result = []
  // 合併數組
  result = [...left, ...subArr, ...right]
  // 這裏改變 this, 就是改變原數組
  for (let i = 0; i < result.length; i++) {
    this[i] = result[i]
  }
  // 返回刪除的數據
  return this.slice(index, index + howmany)
}

let arr = ["Banana", "Orange", "Lemon", "Apple", "Mango"]
let result = arr._splice(2, 1, "sss", "xxx")
console.log(result) // ["sss"]
console.log(arr) // ["Banana", "Orange", "sss", "xxx", "Apple", "Mango"]

Sort

定義和用法

sort() 方法用於對數組的元素進行排序。
排序順序能夠是字母或數字,並按升序或降序。

默認排序順序爲按字母升序。
注意:當數字是按字母順序排列時"40"將排在"5"前面。
使用數字排序,你必須經過一個函數做爲參數來調用。
函數指定數字是按照升序仍是降序排列。
注意: 這種方法會改變原始數組!。

語法

array.sort(sortfunction)

代碼實現—冒泡排序
Array.prototype._sort = function (func) {
  let array = this
 if (arr.length <= 1) { // 若是數組長度小於等於1無需判斷直接返回便可 
      return arr
  }
  if (func == undefined) {
       for (let i = 0; i < array.length; i++) {
           for(let j = 0; j < array.length - i - 1; j++) {
             let temp = ""
             if (String(array[j]) > String(array[j + 1])) {
                // 這是一種交換方式
                temp= array[j + 1];
                array[j+1]=array[j];
                array[j]=temp;
             }
           }
       }
   }
   else if (typeof func == "function") {
       for (let i = 0; i < array.length; i++) {
           for (let j = 0; j < array.length - i - 1; j++) {
             let val = func(array[j], array[j + 1]);
             if (val > 0) {
               // 這也是一種交換方式
               array[j] = array[j] + array[j + 1];
               array[j + 1] = array[j] - array[j + 1];
               array[j] = array[j] - array[j + 1];
             }
           }
       }
   } else if (typeof func !== 'function') {
      throw new TypeError(func + ' is not a function');
  } 
  return array
 }
代碼實現—快速排序
Array.prototype._sort = function (func) {
    let arr = this
    if (arr.length <= 1) { // 若是數組長度小於等於1無需判斷直接返回便可 
      return arr
    }
  let pivotIndex = Math.floor(arr.length / 2) // 取基準點 
  let pivot = arr.splice(pivotIndex, 1)[0] // 取基準點的值,splice(index,1)函數能夠返回數組中被刪除的那個數
  let left = [] // 存放比基準點小的數組
  let right = [] // 存放比基準點大的數組 
  for (let i = 0; i < arr.length; i++){ //遍歷數組,進行判斷分配 
    if (arr[i] < pivot) {
      left.push(arr[i]) // 比基準點小的放在左邊數組 
    } else {
      right.push(arr[i]) // 比基準點大的放在右邊數組 
    }
  }
     //遞歸執行以上操做,對左右兩個數組進行操做,直到數組長度爲<=1; 
  return quickSort(left).concat([pivot], quickSort(right));
}

 let arr1 = [4, 32, 2, 54]
 arr1.sort((a, b) => {
  return a - b
 })
 console.log(arr1) // [2, 4, 32, 54]

 let arr2 = [4, 32, 2, 54]
 arr2.sort()
 console.log(arr2) // [2, 32, 4, 54]
相關文章
相關標籤/搜索