有很多博客都说每当使用hasOwnProperty
循环时都应该使用for..in
检查,但我不明白为什么会这样。无论有没有检查,我们都会得到相同的结果。
查看this fiddle。
答案 0 :(得分:13)
如果您使用{}
创建基本对象,或使用JSON.Parse
从JSON获取基本对象,则hasOwnProperty
全局无用。
但如果您正在扩展(使用原型)“类”,那么它可以帮助您了解您是否正在访问“自己的属性”(直接属性,包括直接属性)。
请注意,基本对象至少有一个(非直接)属性,您可以在console.log({});
循环中使用console.log({}.toString)
或for... in
但it's not enumerable and not seen发现:< / p>
for ... in循环不会迭代不可枚举的属性。 从内置构造函数(如Array和Object)创建的对象具有 从Object.prototype和。继承的非可枚举属性 String.prototype不可枚举,例如String的indexOf 方法或Object的toString方法。循环将迭代所有 对象的可枚举属性或从其继承的属性 构造函数的原型(包括任何覆盖内置的东西 属性)。
答案 1 :(得分:10)
如果没有hasOwnProperty
,您不知道该属性是您的对象的本机属性还是继承自它的原型。
<强> Your modified fiddle 强>
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
从其原型c
继承属性Object
,您将错误地在第一个循环中列出它。
答案 2 :(得分:1)
通常,无论有没有hasOwnProperty
,您都会获得相同的结果,但后者会忽略继承的属性,而不是直接生活在相关对象上。
考虑这个基本的继承系统。狗继承了动物类大师。
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
。
答案 3 :(得分:1)
这就是为什么我们需要在 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
}