雖然有時候遍歷數組只須要 for
循環則足矣,可是若是 API 利用得當,每每能更大程度的提升代碼的可讀性,減小心智負擔~javascript
判斷數組中是否至少有一個項經過了預設的條件,結果返回 boolean
。前端
callback
:執行的回調函數,用於條件判斷。thisArg
:執行函數的 this
指針。判斷數組 [ 1, 2, 3, 5, 6, 7 ]
中是否存在偶數java
const target = [ 1, 2, 3, 5, 6, 7 ] if (target.some(a => a % 2 === 0)) { // do something }
Array.prototype.some = function(fn, thisArg) { // 異常處理 if (this == null) { throw new TypeError('Cannot read property of null or undefined.') } if (typeof fn !== 'function') { throw new TypeError(`${fn} must be a function.`) } // 須要用 Object 包裝一次 this const O = Object(this) const len = O.length || 0 for (let i = 0; i < len; i++) { if (i in O) { if (fn.call(thisArg, O[i], i, O)) { return true } } } return false }
判斷數組中是否所有項都經過了預設的條件,結果返回 boolean
。數組
callback
:執行的回調函數,用於條件判斷。thisArg
:執行函數的 this
指針。判斷數組 [ 1, 2, 3, 5, 6, 7 ]
是否每一個數都是偶數。微信
const target = [ 1, 2, 3, 5, 6, 7 ] if (target.every((num) => num % 2 === 0)) { // do something }
Array.prototype.every = function(fn, thisArg) { // 異常處理 if (this == null) { throw TypeError('Cannot read property of null or undefined') } if (typeof fn !== 'function') { throw TypeError(`${fn} is not a function`) } // 從新包裝一次 this const O = Object(this) const len = O.length || 0 for (let i = 0; i < len; i++) { if (i in O) { if (!fn.call(thisArg, O[i], i, O)) { return false } } } return true }
淺拷貝數組,能夠指定開始和結束下標來對數組某段作拷貝。若是不添加任何參數,那麼會直接拷貝整個數組。函數
begin
(可選參數): 從這個下標開始拷貝,若是爲負數,則表示從倒數第 begin
開始拷貝。end
(可選參數): 從這個下標結束拷貝,若是爲負數,則表示從倒數第 end
結束拷貝。拷貝數組 [ 1, 2, 3, 5, 6, 7 ]
到另一個數組。this
const target = [ 1, 2, 3, 5, 6, 7 ] const temp = target.slice()
Array.prototype.slice = function(begin, end) { if (this == null) { throw new TypeError('cannot read property of null or undefined') } // 若是 end 沒有傳就默認截到數組末尾 end = (typeof end !== 'undefined') ? end : this.length const cloned = [] const len = this.length let i = 0 // 處理下 begin 參數 let start = begin || 0 start = (start >= 0) ? start : Math.max(0, len + start) let upTo = (typeof end == 'number') ? Math.min(end, len) : len if (end < 0) { upTo = len + end } // 計算 upTo 到 start 之間的差值 let size = upTo - start // 若是 size > 0 就計算 // 再拷貝到 cloned 數組中 if (size > 0) { for (i = 0; i < size; i++) { cloned[i] = this[start + i] } } return cloned };
對數組中的每一個元素執行一個由您提供的reducer函數,將其結果彙總爲單個返回值。prototype
callback
指針
reduce
的數組)initValue
計算數組 [ 1, 2, 3, 5, 6, 7 ]
的和。code
const target = [ 1, 2, 3, 5, 6, 7 ] const sum = target.reduce((prev, curr) => prev + curr)
Array.prototype.reduce = function(fn, initValue) { // 異常判斷 if (this == null) { throw new TypeError('Cannot read property of null or undefined') } if (typeof fn !== 'function') { throw new TypeError(`${fn} must be a function`) } const O = Object(this) const len = O.length || 0 let i = 0 let k = 0 let accumulator = initValue // 遍歷並拿到結果 while (i < len) { if (i in O) { if (!accumulator) { accumulator = O[i] } else { accumulator = fn.call(this, accumulator, O[i], i, O) } } else { k++ } i++ } // 空數組異常判斷 if (k >= len) { throw new TypeError('Reduce of empty array with no initial value') } return accumulator }
建立一個新數組,其結果是該數組中的每一個元素調用一次提供的函數後的返回值。
callback
currentValue
index
array
thisArg
將數組 [ 1, 2, 3, 5, 6, 7 ]
轉化成對象數組,格式爲 [{val: 1}, ...]
const target = [ 1, 2, 3, 5, 6, 7 ] const objArr = target.map((num) => { return { val: num } })
Array.prototype.map = function(fn, thisArg) { // 異常判斷 if (this == null) { throw new TypeError('Cannot read property of null or undefined.') } if (typeof fn !== 'function') { throw new TypeError(`${fn} is not a function.`) } const O = Object(this) const len = O.length || 0 const res = [] // 遍歷並拿到結果 for (let i = 0; i < len; i++) { if (i in O) { res.push(fn.call(thisArg, O[i], i, O)) } } return res }
看完上面這些 Polyfill
以後,咱們能夠找到一些規律,以便遇到沒見過的 Polyfill
也能寫出個大概:
this
指針和傳入的回調函數作異常判斷this
用 Object
從新包裝一層搜索「tony老師的前端補習班」關注個人微信公衆號,那麼就能夠第一時間收到個人最新文章。