JavaScript 的怪癖 8:“类数组对象”
发布在JavaScript的12个怪癖(quirks)2013年12月2日view:6543
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

原文: JavaScript quirk 8 array-like objects

译者: Malcolm Yu


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

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

类数组

一个类数组对象:

  • 具有:指向对象元素的数字索引下标以及 length 属性告诉我们对象的元素个数
  • 不具有:诸如 pushforEach 以及 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);
        });
}

我们“通用地”使用了方法 forEachprintArgs 的运行结果如下:

   > 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:参数的处理
评论
发表评论
暂无评论
WRITTEN BY
justjavac(迷渡)
☑辍学生 ☑极客 ☑码农 正在出版「代码之谜」,正在翻译「Javascript Quirks」。 http://justjavac.com
TA的新浪微博
PUBLISHED IN
JavaScript的12个怪癖(quirks)

实际上 javascript 是一个相当简洁的语言,但是也难免会有一些怪癖(quirks)。

本系列文章,需要您了解 ECMAScript 5 和 javascript 的基本知识,凡涉及到比较复杂的,文章中将会给出解释。

本系列文章托管在 github:https://github.com/justjavac/12-javascript-quirks,您可以通过 pull reqeust 的方式参与翻译。

参考资料:ECMAScript: ES.next versus ES 6 versus ES Harmony (中文)

我的收藏