13

有很多博客说hasOwnProperty每当使用循环时都应该使用检查for..in,但我不明白为什么会这样。无论有没有检查,我们都会得到相同的结果。

看看这个小提琴

4

4 回答 4

16

如果您使用 来创建一个基本对象{},或者使用 来从 JSON 中获取它JSON.parse,那么hasOwnProperty全局无用。

但是,如果您正在扩展“类”(使用原型),那么它可以帮助您了解您是否正在访问“自己的属性”(直接属性,包括直接函数)。

请注意,一个基本对象至少有一个(不是直接的)属性,您可能会用console.log({});or发现它,console.log({}.toString)它不是可枚举的,也不能for... in循环中看到:

for...in 循环不会迭代不可枚举的属性。从 Array 和 Object 等内置构造函数创建的对象从 Object.prototype 和 String.prototype 继承了不可枚举的不可枚举属性,例如 String 的 indexOf 方法或 Object 的 toString 方法。循环将遍历对象的所有可枚举属性,或者它从其构造函数的原型继承(包括任何覆盖内置属性的属性)。

于 2012-07-03T15:18:38.230 回答
12

没有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
​

在这种情况下,从它的 Prototypeobj1继承该属性,您将错误地在您的第一个循环中列出它。cObject

于 2012-07-03T15:25:22.703 回答
1

通常你会得到相同的结果有或没有hasOwnProperty,但后者会忽略继承而不是直接存在于相关对象上的属性。

考虑这个基本的继承系统。狗继承自主 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'});

如果我们查看fidohasOwnProperty可以帮助我们确定哪些是它自己的属性(名称),哪些是继承的。

for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);

...警报name=Fido但不是is_animal=true

于 2012-07-03T15:29:55.347 回答
0

这就是为什么我们需要在 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
}

于 2021-05-23T16:59:55.377 回答