類陣列是指具有數字索引下標並且有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
複製程式碼