【发布时间】:2012-07-04 01:35:16
【问题描述】:
有很多博客说只要使用for..in 循环就应该使用hasOwnProperty 检查,但我不明白为什么会这样。无论有没有检查,我们都会得到相同的结果。
查看this fiddle。
【问题讨论】:
-
检查这个小提琴jsfiddle.net/gFmXM/1
标签: javascript
有很多博客说只要使用for..in 循环就应该使用hasOwnProperty 检查,但我不明白为什么会这样。无论有没有检查,我们都会得到相同的结果。
查看this fiddle。
【问题讨论】:
标签: javascript
如果您使用{} 创建一个基本对象,或者使用JSON.parse 从JSON 中获取它,那么hasOwnProperty 全局无用。
但是,如果您正在扩展“类”(使用 prototype),那么它可以帮助您了解您是否正在访问“自己的属性”(直接属性,包括直接函数)。
请注意,基本对象至少有一个(不是直接的)属性,您可能会在 console.log({}); 或 console.log({}.toString) 但 it's not enumerable and not seen 在 for... in 循环中发现它:
for...in 循环不会遍历不可枚举的属性。 从 Array 和 Object 等内置构造函数创建的对象具有 从 Object.prototype 继承的不可枚举属性和 不可枚举的String.prototype,比如String的indexOf 方法或 Object 的 toString 方法。循环将遍历所有 对象的可枚举属性或从其继承的 构造函数的原型(包括任何覆盖内置的 属性)。
【讨论】:
hasOwnProperty 并非无用且必要。假设有人修改了Object.prototype,就像克里斯托夫的回答一样。即使是一个简单的对象,如果没有hasOwnProperty,你也会得到不可预测的结果。
如果没有hasOwnProperty,您将不知道该属性是对象的本机属性还是继承自它的原型。
var obj1 = {a:"10",b:"20"};
Object.prototype.c = "prototype:30";
var i;
for(i in obj1) {
document.getElementById("div1").innerHTML += obj1[i]+" ";
}
// result 10 20 prototype:30
for(i in obj1) {
if(obj1.hasOwnProperty(i)) {
document.getElementById("div2").innerHTML += obj1[i] +" ";
}
}
// result 10 20
在这种情况下,obj1 从它的原型Object 继承属性c,你会错误地在你的第一个循环中列出它。
【讨论】:
无论是否使用hasOwnProperty,您通常都会得到相同的结果,但后者会忽略继承的属性,而不是直接存在于相关对象上。
考虑这个基本的继承系统。 Dogs 继承自 Animal 主类。
function Animal(params) { this.is_animal = true; }
function Dog(params) { for (var i in params) this[i] = params[i]; }
Dog.prototype = new Animal();
var fido = new Dog({name: 'Fido'});
如果我们查看fido,hasOwnProperty 可以帮助我们确定哪些是它自己的属性(名称),哪些是继承的。
for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);
...提醒name=Fido,但不提醒is_animal=true。
【讨论】:
这就是为什么我们需要在 for..in 语句中使用 hasOwnProperty() 方法:这不是无用的,这对于确保代码安全并使其始终做正确的事情非常重要。因为某些库或某些依赖项可能会触及随时在您的程序上下文中使用 Object.prototype,如果没有检查 hasOwnProperty,您的 for...in 语句可能会迭代意外的键。因此,您需要使用 hasOwnProperty() 使您的 for...in 语句安全。
var obj = {
a: 1,
b: 2
};
Object.prototype.haha = 3;
for (var k in obj) {
if (obj.hasOwnProperty(k)){
console.log(k); // prints a, b
}
}
var obj = {
a: 1,
b: 2
};
Object.prototype.haha = 3;
for (var k in obj) {
console.log(k); // prints a, b, haha
}
【讨论】: