为啥在 Javascript 中使用类似数组的对象?

Posted

技术标签:

【中文标题】为啥在 Javascript 中使用类似数组的对象?【英文标题】:Why use an array-like object in Javascript?为什么在 Javascript 中使用类似数组的对象? 【发布时间】:2017-10-21 16:19:03 【问题描述】:

我知道由于 javascript 允许对象使用数字键,因此类似数组的对象的存在在技术上是可能的,但为什么它们会变得普遍呢?

也许想法是这些类似数组的对象不只是有数字键,例如arguments 具有 callee 属性,因此它们不能是适当的数组来容纳这些属性。

但在 javascript 中,将数组视为对象并使用非数字键是完全有效的:

var myArguments = []; 
myArguments[0] = 0; 
myArguments['callee'] = function()console.log('callee');

如果对象是类数组的,并且可以访问从数组原型继承的函数,那么将其改为类数组对象有什么好处?


编辑:如果我的问题不清楚,类似数组的对象将类似于 arguments 对象,它具有从零开始的连续数字属性,并且长度属性比最高值小一数字键。它也不从数组原型继承,也不提供对数组方法的访问。

【问题讨论】:

array-like - 你有一个数组,没有什么“喜欢”它 - 就像 javascript 中的任何东西一样,数组继承自对象,因此非数字“属性键”是可能的 并不总是可以从(子类)Array 继承,所以如果你想使用构造函数创建这样的对象(所有实例都链接到同一个原型),你可以不要使用实际的Array。但是您仍然可以使用.call().apply() 在类似数组的对象上使用(某些)数组方法,所以... @nnnnnn 这实际上很有道理,尤其是对于像htmlCollection 这样的东西,对于arguments 来说仍然有点混乱,尽管它直接从对象原型继承。 为什么它们变得普遍?” - 我认为它们从未变得普遍。 【参考方案1】:

实际上JS中的数组是一个对象:)

只要你需要数组,创建类似数组的对象是个坏主意,因为 JS 引擎优化了数组的速度。 然而,这是可能的。

【讨论】:

但问题是为什么创建不是实际数组的类数组对象是(相对)普遍的,而不是它是否是一个好主意。【参考方案2】:

没有太大的优势,因为您可以以非常相似的方式访问对象和数组,array[number] 用于数组,object.properyobject["property"] 用于对象。在我看来,数组更适合存储数据,而不是函数,我认为对象更适合存储函数集。例如,数组可以将您的答案存储在记忆游戏中,但对象会存储游戏的命令,例如开始或结束。

【讨论】:

【参考方案3】:

编辑:正如@Bergi 所说,我忘记为对象添加长度属性。另外,我意识到我的答案不相关。所以我经过短暂的研究后更新了它。

在 Typescript 中,类数组对象的定义如下:

interface ArrayLike<T> 
  length: number;
  [n: number]: T;

类数组对象有两个主要示例:argumentsHTMLCollection。使用类数组对象的原因是将数组仅用作数据容器而没有任何行为。如您所见,如果您尝试在arguments 对象上使用forEach,您将收到类型错误,因为它没有在其上定义。如果您严格相信您正在创建的数组仅用作数据容器而没有任何方法,那么请使用类似数组的对象。然而,重要的是要注意它们日益稀缺,尤其是在 ES6 之后。

【讨论】:

一个类似数组的对象至少有一个.length属性【参考方案4】:

我认为使用 Array-Like 对象的最大优势,是对象本身。对象的开销比数组少。 可以阅读:Array vs. Object efficiency in JavaScript

使用对象的另一个优点是,Language 不必像在 Array 中那样创建/分配连续的内存。该对象本质上更具动态性。数组必须提前创建一个内存块。并更新过载。

阅读更多:How are the JavaScript Arrays internally resizing?

另一个因素,我认为在地图或对象中查找更快。

【讨论】:

"数组必须提前创建一个内存块。" - 不,它没有。引擎可以以与对象相同的方式对其进行优化。

以上是关于为啥在 Javascript 中使用类似数组的对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥函数的参数对象不是 Javascript 中的数组?

为啥数字数组,更多数据排序比对象数组更快,Javascript中的数据更少?

为啥以下 javascript 数组排序决定我的两个排序顺序参数未定义?

为啥javascript在添加时会将对象更改为其他内容? [关闭]

在 JavaScript 中实现类似数组的行为而不使用数组

为啥 Javascript 不能从字符串文字中解析这个 JSON 数组?