JavaScript数组的子类化破坏了快速枚举

Subclassing JavaScript Array breaks fast enumeration

本文关键字:坏了 枚举 数组 子类 JavaScript      更新时间:2023-09-26

我正在使用原型对Array进行子类化,方法是:

MyArray = function()
{
   Array.apply(this, arguments);
};
MyArray.prototype = new Array();

所有操作都如预期的那样正常,我可以通过以下方式初始化"MyArray"实例:

var arr = new MyArray();
arr.push(1, 2, 3);

问题是MyArray实例的快速枚举被破坏了,实际上是以下循环:

for (var i in arr)
{
   console.log(i);
}

打印:0,1,2,长度

在实践中,类的每个方法/属性都包含在枚举中。在普通数组中,代码只打印0、1、2(这些数字是数组的索引)。

所以。。。我的问题是:如何通过保留快速枚举来扩展Array?

ps:在目标C中,为了实现快速枚举,你必须重写一个方法。。。在JavaScript中有特殊的重写方法吗?

注意:很明显,我对"MyArray"的实际实现略有不同,但我发布的代码足以生成一个异常的快速枚举循环。不要问我为什么要扩展Array,我有正当的理由;)

永远不应该使用for (var x in obj)枚举数组元素,因为它迭代对象的可枚举属性,而不仅仅是数组元素,正如您所看到的,数组元素可以包括数组元素之外的内容。此外,这种迭代方法不能保证以任何给定的顺序返回属性,因此数组元素的顺序可能不正确。

在最新的浏览器中,您可以使用Object.defineProperties()方法创建属性,并指定属性是否可枚举,但这仍然不意味着使用for (var x in obj)枚举数组的元素是正确的。应该始终使用这种类型的形式来迭代数组元素:for (var i = 0, len = arr.length; i < len; i++)或像array.forEach(callback [, thisArg])这样的内置迭代器。