类数组是指具有数字索引下标并且有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) // 1console.log(obj) //Object {0: 2, 1: 3, length: 2}Array.forEach(obj, function(i, n){ console.log(i,n)})// 2 0// 3 1复制代码