JavaScript 的怪癖 8:“类数组对象”

原文: JavaScript quirk 8 array-like objects

译者: Malcolm Yu


此文是 javascript 的 12 个怪癖(quirks) 系列的第八篇。

JavaScript中有一些看起来像却又不是数组的对象,唤作类数组。 本文旨在探究类数组的确切含义和高效的使用方式。

类数组

一个类数组对象:

  • 具有:指向对象元素的数字索引下标以及 length 属性告诉我们对象的元素个数
  • 不具有:诸如 push 、 forEach 以及 indexOf 等数组对象具有的方法

两个典型的类数组的例子是:DOM方法 document.getElementsByClassName() 的返回结果(实际上许多DOM方法的返回值都是类数组)以及特殊变量 arguments [1]。例如你可以通过以下方法确定函数参数的个数:

arguments.length

你也可以获取单个参数值,例如读取第一strong text个参数:

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()

引用

  1. JavaScript 的怪癖 5:参数的处理
类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组

let arrayLike = {
'0' : 'a',
'1' : 'b',
'2' : 'c',
length : 3
};
let arr1 = Array.prototype.slice.call(arrayLike);
let arr2 = [].slice.call(arrayLike);
let arr3 = Array.from(arrayLike);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值