for..in 和 hasOwnProperty

IT技术 javascript
2021-02-11 10:33:17

可能的重复:
如何在 JavaScript 中检查对象是否具有特定属性?

我在 Twitter 的 JavaScript 文件中发现了以下代码段。为什么他们需要调用hasOwnProperty函数才能看到dictkey属性?用于循环运行在“字典”,这意味着“字典”具有“键”各自的“钥匙”。我错过了一个点吗?

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

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

这样你就可以保证只有那个对象实例本身的键。

@ScepticalJulefor..in专门用于获取可枚举的属性,包括继承的属性。如果您只想要可枚举的自己的属性,则可以使用 for for (const key of Object.keys(obj))属性表的可枚举性和所有权
2021-04-04 10:33:17
我只是不明白像 JS 这样流行和快速发展的语言在这么多年和标准之后如何仍然没有一个合适的对象迭代循环,你不必调用hasOwnProperty()每个循环步骤。
2021-04-08 10:33:17
@ScepticalJule 这通常是我在 Web 开发方面的问题。即使它变得如此流行,今天的所有 webdev 技术都只是在蹩脚的 30 岁技术之上构建层。我希望我们放弃一切,制作一些真正强大、直观且真正适合当今时代所需的东西。
2021-04-10 10:33:17

hasOwnProperty方法可以让你知道,如果一个属性是直接在对象的实例或它的原型链继承。

考虑以下

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

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

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

即,您有一个带有属性对象 dictfoo并且foobar它也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,让您甚至可以区分与继承的同名的属性。

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

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

但是这个函数是从Object类继承的,所以hasOwnProperty会告诉你这个键是属于字典的还是继承的。

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

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

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

prototype.js 做错了很多事情。
2021-03-23 10:33:17