对象、数组 傻傻分不清楚
优质
小牛编辑
132浏览
2023-12-01
JavaScript中有一些看起来像却又不是数组的对象,唤作类数组。 本文旨在探究类数组的确切含义和高效的使用方式。
类数组
一个类数组对象:
- 具有:指向对象元素的数字索引下标以及
length
属性告诉我们对象的元素个数 - 不具有:诸如
push
、forEach
以及indexOf
等数组对象具有的方法
两个典型的类数组的例子是:DOM方法 document.getElementsByClassName()
的返回结果(实际上许多DOM方法的返回值都是类数组)以及特殊变量 arguments
[[1][]]。例如你可以通过以下方法确定函数参数的个数:
arguments.length
你也可以获取单个参数值,例如读取第一个参数:
arguments[0]
如果这些对象想使用数组的方法,就必须要用某种方式“借用”。由于大部分的数组方法都是通用的,因此我们可以这样做。
通用方法
所谓的通用方法就是不强制要求函数的调用对象 this
必须为数组,仅需要其拥有 length
属性和数字索引下标即可。 通常来讲,你可以用如下的方式在数组 arr
上调用方法 m
:
arr.m(arg0, arg1, ...)
所有的函数都拥有一个 call
方法来让我们用这样一种方式进行上述调用:
Array.prototype.m.call(arr, arg0, arg1, ...)
call
方法的第一个参数就是函数 m
的调用对象 this
的值(在这个例子里就是 arr
)。 因为我们直接调用方法 m
,而非通过数组对象 arr
,因此我们可以为本方法更改任意的 this
值。
例如改为 arguments
:
Array.prototype.m.call(arguments, arg0, arg1, ...)
例子
让我们来看一个具体的例子。 下面的 printArgs
列出了函数的全部参数值。
function printArgs() {
Array.prototype.forEach.call(arguments,
function (arg, i) {
console.log(i+'. '+arg);
});
}
我们“通用地”使用了方法 forEach
。 printArgs
的运行结果如下:
> printArgs()
> printArgs('a')
0. a
> printArgs('a', 'b')
0. a
1. b
你甚至可以应用通用方法给普通的对象:
> var obj = {};
> Array.prototype.push.call(obj, 'a');
1
> obj
{ '0': 'a', length: 1 }
在上述例子中,length
属性原本不存在并以0为初始值自动创建。
将类数组对象转化为数组
有时候处理类数组对象的最好方法是将其转化为数组。 这项工作也可以使用通用方法来完成:
Array.prototype.slice.call(arguments)
对于正常复制数组对象而言,我们额外使用了 call
的方法。
arr.slice()