JavaScript 中 for...in 循环的正确用法与 hasOwnProperty 过滤

作者:纸飞机时间:2026-10-28 12:36:12浏览:660

本文详解 JavaScript 中 for...in 循环的机制,指出其会遍历 enumerable 为 true 的属性及原型链。重点讲解如何通过 hasOwnProperty 方法过滤非自身属性,避免 Object.prototype 扩展导致的错误,强调这是处理对象遍历的唯一正确写法。

for...in 循环机制与注意事项

首先展示一个示例代码:


// Poisoning Object.prototype
Object.prototype.bar = 1;

var foo = {moo: 2};
for(var i in foo) {
 console.log(i); // prints both bar and moo
}

在使用 for...in 循环时,需要特别注意两个关键点。第一,该循环会忽略 enumerable 属性被设置为 false 的属性,例如数组的 length 属性。第二,由于 for...in 会遍历整个原型链,如果原型链过长,可能会对性能产生负面影响。

enumerable 是一个相对陌生的概念,在 JavaScript 原生代码中较少直接见到。它实际上是借鉴自 Ruby 语言。创建 enumerable 的目的并非独立使用,而是采用混合使用的方式。Prototype 库中的许多方法都混合使用了 enumerable,因此它可视为 Prototype 库的基石。此处不作深入展开,详细内容可参考 Enumerable 相关文档。由于无法直接修改 for...in 循环本身的行为,我们需要采取其他方法来过滤掉不希望出现在循环中的属性。根据《Javascript学习笔记之对象篇(三) : hasOwnProperty》的介绍,hasOwnProperty 方法可以实现这一过滤功能。

使用 hasOwnProperty 过滤属性

使用 hasOwnProperty 进行过滤

继续沿用之前的示例:


// Poisoning Object.prototype
Object.prototype.bar = 1;

var foo = {moo: 2};
 for(var i in foo) {
 if (foo.hasOwnProperty(i)) {
  console.log(i);
 }
 }

这是唯一正确的写法。由于使用了 hasOwnProperty 方法,此次循环仅输出 moo。如果不使用 hasOwnProperty 进行过滤,当 Object.prototype 被扩展时,就会出现错误。目前许多框架都会从 Object.prototype 扩展方法,因此在使用这些框架时,若使用未通过 hasOwnProperty 过滤的 for...in 循环,就会遇到问题。

总结

建议养成使用 hasOwnProperty 过滤属性的习惯。不要对运行环境做任何假设,无论原生原型对象是否被扩展,都应保持这一最佳实践。

作者最新文章