Joh*_*sch 5 javascript arrays enumerable for-in-loop
我最近偶然发现了在JavaScript中使用for..in循环的问题.
根据这个 问题的答案,for..in旨在枚举对象的属性,包括继承的属性.
如果是这样,为什么我们能够使用Object.defineProperty将属性定义为不可枚举?这不符合for..in的全部意图吗?或者它被认为是不好的做法,应该避免?
另外,为什么我们要首先以这种方式迭代所有属性(即使用for..in循环)?什么时候可以派上用场?
为什么不将所有(Array)原型扩展定义为不可枚举并继续使用for..in和数组?
问题是对象属性只有一个命名空间(暂时忽略ES2015中的符号功能).您确实希望可以枚举某些对象属性,而有些属性则不可.包含对象数据的属性和与其他对象的关系与方法名称共享该命名空间.
该for ... in循环看起来不仅在对象的直接参与的特性,而且还涨了原型链.这可能是最可能用于非可枚举属性的:您可能希望放在原型对象上的方法可能不需要是可枚举的.
对我来说,for ... in在迭代Array实例的数字名称属性时不使用的真正原因是,无法保证您将以任何特定顺序迭代索引.虽然大多数运行时系统确实以明显的顺序返回数字名称属性,但该语言的规范绝对不需要这样.通过在普通for循环中使用显式数字索引,可以显式控制迭代顺序.
编写JavaScript代码以供在其无法控制的其他代码运行的情境中使用的人(想想广告支持的网站或具有大量度量工具的网站)知道依赖于内置原型而不会被污染随机垃圾是非常不明智的.使用for ... in将您的代码置于对第三方代码有贡献的最差编码器的支配下.
现代实现有Object.keys(),它返回对象的可枚举"自己的"属性名称; 也就是说,直接在对象上的属性名称,而原型链中没有属性的名称.