类数组是指具有数字索引下标并且有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
复制代码