# 类数组对象

所谓类数组对象:

拥有一个 length 属性和若干索引属性的对象

举个例子

var array = ['name', 'age', 'sex']
var arrayLike = {
  0: 'name',
  1: 'age',
  2: 'sex',
  length: 3
}

为什么叫类数组呢,我们从读写、获取长度、遍历三方面看看二者的区别

# 读写

console.log(array[0]) // 'name'
console.log(arrayLike[0]) // 'name'

array[0] = 'new name'
arrayLike[0] = 'new name'

# 长度

console.log(array.length) // 3
console.log(arrayLike.length) // 3

# 遍历

for(var i = 0, len = array.length; i < len; i++) {
  //
}
for(var i = 0, len = arrayLike.length; i < len; i++) {
  //
}

# 总结

综上所述,数组、类数组几乎一模一样,区别在于类数组无法调用数组的方法:

arrayLike.push('4') // arrayLike.push is not a function

# 调用数组方法

如果类数组想调用数组的方法,该如何做?

# 使用 Function.call

Array.prototype.join.call(arrayLike, '&')
Array.prototype.slice.call(arrayLike, 0)
Array.prototype.map.call(callLike, function(item) {
  return item.toUpperCase()
})

# 类数组转成数组

Array.from(arrayLike)
Array.prototype.slice.call(arrayLike)
Array.prototype.splice.call(arrayLike, 0)
Array.prototype.concat.apply([], arrayLike)

# Arguments 对象

Arguments 对象就是最常见的类数组,它一定包含 length、callee等

# length 属性

表示实参的长度

# callee 属性

通过 callee 属性可以调用函数自身

// 经典闭包题

var data = []
for(var i = 0; i < 3; i++) {
  (data[i] = function() {
    console.log(arguments.callee.i)
  }).i = i
}

data[0]() // 0
data[1]() // 1
data[2]() // 2

# arguments 和对应参数的绑定

在非严格模式下,arguments 会与对应的实参共享,也就是说修改它们会影响彼此;在严格模式下,二者不会共享。