为啥在 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.propery
和object["property"]
用于对象。在我看来,数组更适合存储数据,而不是函数,我认为对象更适合存储函数集。例如,数组可以将您的答案存储在记忆游戏中,但对象会存储游戏的命令,例如开始或结束。
【讨论】:
【参考方案3】:编辑:正如@Bergi 所说,我忘记为对象添加长度属性。另外,我意识到我的答案不相关。所以我经过短暂的研究后更新了它。
在 Typescript 中,类数组对象的定义如下:
interface ArrayLike<T>
length: number;
[n: number]: T;
类数组对象有两个主要示例:arguments
和 HTMLCollection
。使用类数组对象的原因是将数组仅用作数据容器而没有任何行为。如您所见,如果您尝试在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 数组排序决定我的两个排序顺序参数未定义?