【问题标题】:Should hasOwnProperty still be used with for..in statementshasOwnProperty 是否仍应与 for..in 语句一起使用
【发布时间】:2012-07-04 01:35:16
【问题描述】:

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

查看this fiddle

【问题讨论】:

标签: javascript


【解决方案1】:

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

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

请注意,基本对象至少有一个(不是直接的)属性,您可能会在 console.log({});console.log({}.toString)it's not enumerable and not seenfor... in 循环中发现它:

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

【讨论】:

  • 当您无法完全控制页面中的代码时,hasOwnProperty 并非无用且必要。假设有人修改了Object.prototype,就像克里斯托夫的回答一样。即使是一个简单的对象,如果没有hasOwnProperty,你也会得到不可预测的结果。
  • 我想说的是,您无法完全控制的混乱代码与使用 {} 创建基本对象或从 JSON 获取它跨度>
【解决方案2】:

如果没有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 从它的原型Object 继承属性c,你会错误地在你的第一个循环中列出它。

【讨论】:

    【解决方案3】:

    无论是否使用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'});
    

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

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

    ...提醒name=Fido,但不提醒is_animal=true

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-04
        • 1970-01-01
        • 2010-09-07
        • 1970-01-01
        • 1970-01-01
        • 2012-09-25
        • 2012-09-26
        相关资源
        最近更新 更多