# 类数组

# 什么是类数组?

类数组是相对于数组而言的。但并不是真正的数组。而且是有严格的的格式。

var likeArray = {0: 'a', 1: 'b', length: 2};

必须是具备 length 属性的。

# 为什么要有类数组

因为数组上已经封装了许多的方法了,如果我们只是想创建一个简单的类型,Array 上面的方法已经有很多了。我们可以创建一个类似它的,但是却不会那么的冗余。

# 类数组有什么?

  1. argument;

  2. document.getElementsByTagName

# argument

argument 是一个类数组,上面有 callee、length、遍历器等属性。

  1. length 属性
function foo(a, b) {
    console.log(argument.length);  // 形参的个数 2
}
console.log(foo.length); // 实参的个数 1
foo(1);

  1. callee
function foo() {
    argument.callee();  // 可以递归的调用自己 
}
foo();


解决for循环问题
var data = [];
for (var i = 0; i < 5; i++) {
    (data[i] = function() {
        console.log(arguments.callee.i);
    }).i = i;
}
data[0]();   0
data[1]();   1

  1. 参数绑定
function foo(a, b, c, d) {
    a = 1;
    console.log(arguments[0], a);  // 1  1

    arguments[1] = 2;
    console.log(arguments[1], b);  // 2  2

    c = 10;
    console.log(arguments[2], c); // undefined 10

    arguments[3] = 20;
    console.log(arguments[3], d);  // 20  undefined
}
foo(100, 200);

实参与arguments 的值是共享的。 但是没有传入时,是不共享的。

在严格模式下是不共享的。

function foo(a, b) {
    a = 10;
    console.log(arguments[0], a);  // 1  10
}
foo(1, 2);

# 类数组转为数字

var likeArray = [0: 'a', 1: 'b', length: 2];

Array.prototype.slice.call(likeArray); // ['a', 'b']

Array.prototype.splice.call(likeArray, 0); // ['a', 'b']

Array.from(likeArray);  // ['a', 'b']

Array.prototype.concat.apply([], likeArray);

如果是 arguments ,可以直接使用 ...剩余参数。

甚至是可以直接给 likeArray.__proto__ = Array.prototype;