【问题标题】:for..in and hasOwnProperty [duplicate]for..in 和 hasOwnProperty [重复]
【发布时间】:2012-09-25 23:47:56
【问题描述】:

可能重复:
How do I check if an object has a specific property in JavaScript?

我在 Twitter 的 JavaScript 文件中发现了以下 sn-p。为什么他们需要调用hasOwnProperty 函数才能看到dictkey 属性? for 循环为 'dict' 中的每个 'key' 运行,这意味着 'dict' 有 'key'。我错过了一点吗?

function forEach(dict, f) {
    for (key in dict) {
        if (dict.hasOwnProperty(key))
            f(key, dict[key]);
    }
}

【问题讨论】:

  • 这里解释得很好:stackoverflow.com/a/136411/27512
  • 好像key 是全球性的,这段代码是从哪里来的,你能发个链接吗?
  • @elclanrs 我错了。这段代码来自 Chrome 的 utils.js
  • @elclanrs 更有可能他只是不知道他的代码正在创建这个全局,很容易忘记 for in 循环中的varedit:哦,我刚读到这不是他的代码……有趣
  • 他一定是写了然后忘了。谷歌代码不可能漏掉括号而忘记var

标签: javascript


【解决方案1】:

因为如果您不这样做,它将遍历原型链上的每个属性,包括您不知道的属性(可能是由弄乱原生对象原型的人添加的)。

这样您就可以保证只有该对象实例本身上的键。

【讨论】:

  • 我只是不明白在这么多年和标准之后,像 JS 这样如此流行和迅速发展的语言如何仍然不是一个适当的循环对象迭代,你不必调用 @987654322 @ 在每个循环步骤上。
  • @ScepticalJule for..in 专门用于获取可枚举的属性,包括继承的属性。如果你只想要enumerable own 属性,你可以使用for (const key of Object.keys(obj))Enumerability and ownership of properties table
  • @ScepticalJule 这是我一般的 Web 开发问题。即使它变得如此流行,今天的所有 webdev 技术都只是在 30 年的糟糕技术之上不断构建层。我希望我们放弃这一切,做一些真正强大、直观且真正适合我们在这个时代所需要的东西。
【解决方案2】:

hasOwnProperty 方法让您知道属性是直接位于对象的实例上还是继承自其原型链。

考虑以下

function ObjWithProto() {
    this.foo = 'foo_val';
}

ObjWithProto.prototype = {bar: 'bar_val'};

var dict = new ObjWithProto();
dict.foobar = 'foobar_val';

即,您有一个 Object dict 具有属性 foofoobar,它还从其原型链继承了属性 bar

现在通过您的代码(修改版本)运行它:

function forEach(dict) {
    var key;
    for (key in dict) {
        if (dict.hasOwnProperty(key)) 
            console.log('has', key, dict[key]);
        else 
            console.log('not', key, dict[key]);
    }
}
forEach(dict);

你会看到

has foo foo_val
has foobar foobar_val
not bar bar_val

这让您可以将对象本身的属性和它继承的属性(通常是与循环无关的方法)分开。

此外,如果您现在执行dict.bar = 'new_bar_val';,最后的结果将更改为has bar new_bar_val,让您甚至可以区分与继承的同名属性。

【讨论】:

    【解决方案3】:

    JavaScript 中的每个对象都是一个字典。这意味着“toString”和其他所有方法都是每个对象的键:

    var myObj = {};
    console.log(myObj["toString"]);
    

    但是这个函数是继承自 Object 类的,所以 hasOwnProperty 会告诉你这个键是由字典拥有还是被继承。

    "toString" in myObj; // true
    myObj.hasOwnProperty("toString") // false
    

    【讨论】:

      【解决方案4】:

      blockhead is 就在这里。例如,Prototype.js 框架用于通过额外的辅助方法扩展原生数组(我不知道当前框架版本的情况)。

      因此直接使用“for (key in dict)”将返回 div 的所有元素以及对辅助方法的引用。这有点出乎意料:)

      【讨论】:

      • prototype.js 做错了很多事情。
      猜你喜欢
      • 2015-01-04
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2018-03-03
      • 2014-02-11
      相关资源
      最近更新 更多