JavaScript:不可枚举属性 - 何时以及为何?

JavaScript: Unenumerable properties - when and why?

我最近偶然发现了在 JavaScript.

中对数组使用 for..in 循环的问题

根据this问题的回答,for..in的目的是枚举一个对象的属性,包括继承的属性。

如果是这样,为什么我们能够使用 Object.defineProperty 将属性定义为不可枚举?这不是违背了 for..in 的全部意图吗?或者它被认为是不好的做法,应该避免?

此外,为什么我们首先要以这种方式遍历所有属性(即使用 for..in 循环)?这个什么时候能派上用场?

为什么不将所有(数组)原型扩展定义为不可枚举并继续使用 for..in 数组?

问题是对象属性只有一个命名空间(暂时忽略 ES2015 中的 Symbol 特性)。有一些对象属性是您 想要可枚举的,而有些则不是。包含对象数据和与其他对象的关系的属性与方法名称共享该命名空间。

for ... in 循环不仅查看直接涉及的对象的属性,还查看原型链上游。这可能是不可枚举属性最有可能的用途:您可能想要放在原型对象上的方法可能不需要是可枚举的。

对我来说,当您遍历 Array 实例的数字名称属性时不使用 for ... in 的真正原因是,不能保证您会以任何特定顺序遍历索引。尽管大多数运行时系统 以明显的顺序返回数字名称属性,但语言规范绝对不要求这种情况。通过在普通 for 循环中使用显式数字索引,您可以显式控制迭代顺序。

编写 JavaScript 代码的人在有其他代码 运行 他们无法控制的上下文中使用(想想广告支持的网站,或者有很多度量工具的网站) 知道依赖内置原型不被随机垃圾污染是非常不明智的。使用 for ... in 会使您的代码受到为该第三方代码做出贡献的最差编码人员的摆布。

现代实现有 Object.keys(),其中 returns 对象的可枚举 "own" 属性 名称;也就是说,直接在对象上的属性名称,none 来自原型链。