關於在類陣列中使用陣列方法

zifeiyu發表於2018-12-04

類陣列是指具有數字索引下標並且有length屬性的物件

{'1': 'a', '2': 'b', length: 3}
複製程式碼

由於它們並不是真正的陣列並不能使用陣列的方法;那麼有什麼方法可以讓他們用上方便的陣列方法呢?

藉助call和apply

(function() {
    Array.prototype.push.call(arguments, 4)
    console.log(arguments)
    // [1,2,3,4]/{ '0': 1, '1': 2, '2': 3, '3': 4 }
})(1,2,3)
複製程式碼

利用反柯里化優化該方法

我們在函式原型上新增一個方法uncurrying

Function.prototype.uncurrying = function() {
    let self = this;
    // 這裡是拿出引數組中的第一個引數賦值給obj,剩下的引數就是arguments
    return function() {
        let obj = Array.prototype.shift.call(arguments)
        return self.apply(obj, arguments)
      }
}
複製程式碼

使用方法

// 生成一個可以隨處使用的push方法
let push = Array.prototype.push.uncurrying()
;(function() {
    push(arguments, 4)
    console.log(arguments)
    // [1,2,3,4]/{ '0': 1, '1': 2, '2': 3, '3': 4 }
})(1,2,3)
複製程式碼

甚至我們可以直接把類陣列不支援的方法直接複製到array物件上。

var arr = ['push', 'shift', 'forEach']
for(let i = 0, fn; fn = arr[i++];) {
    Array[fn] = Array.prototype[fn].uncurrying()
}

var obj = {
    length: 2,
    '0': 1,
    '1': 2
}

Array.push(obj, 3);
console.log(obj) //Object {0: 1, 1: 2, 2: 3, length: 3}
Array.shift(obj) // 1
console.log(obj) //Object {0: 2, 1: 3, length: 2}
Array.forEach(obj, function(i, n){
  console.log(i,n)
})
// 2 0
// 3 1
複製程式碼

相關文章