for..in和hasOwnProperty

scu*_*yxx 62 javascript

可能重复:
如何查看对象在Javascript中是否具有属性?

我在Twitter的JS文件中找到了以下代码段.我想知道他们为什么需要调用hasOwnProperty函数看到dictkey财产?for循环正在为'dict'中的每个'key'运行,这意味着'dict'有'key',我错过了一个点吗?

function forEach(dict, f) {
    for (key in dict) {
        if (dict.hasOwnProperty(key))
            f(key, dict[key]);
    }
}
Run Code Online (Sandbox Code Playgroud)

blo*_*ead 68

因为如果你不这样做,它将循环遍历原型链上的每个属性,包括那些你不了解的属性(可能是由于某人搞乱了原生对象原型而添加的).

这样,您只能保证该对象实例本身的键.

  • 我只是不明白像 JS 这样如此流行且快速发展的语言经过这么多年和标准仍然没有一个合适的对象迭代循环,您不必在每个循环步骤中调用“hasOwnProperty()” 。 (2认同)
  • @ScepticalJule `for..in` 专门用于获取可枚举属性,包括继承的属性。如果您只想*可枚举自己的*属性,则可以使用 for `for (const key of Object.keys(obj))`。[属性表的可枚举性和所有权](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#detection_table) (2认同)

Pau*_* S. 33

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

考虑以下

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

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

var dict = new ObjWithProto();
dict.foobar = 'foobar_val';
Run Code Online (Sandbox Code Playgroud)

即你有一个具有属性的对象 dict,foo并且foobarbar从它的原型链继承了一个属性.

现在运行它(代码的修改版本)

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 );
Run Code Online (Sandbox Code Playgroud)

你会看见

has foo foo_val
has foobar foobar_val
not bar bar_val
Run Code Online (Sandbox Code Playgroud)

这使您可以分离对象拥有的属性和它继承的属性(通常是与循环无关的方法)

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


A. *_*ada 5

javascript上的每个对象都是一个字典,这意味着"toString"和其他所有方法都是每个Object的关键

var myObj = {};
console.log(myObj["toString"]);
Run Code Online (Sandbox Code Playgroud)

但是此函数继承自Object类,因此hasOwnProperty会告诉您此键是否由字典拥有或是否继承.

"toString" in myObj; // true
myObj.hasOwnProperty("toString") // false
Run Code Online (Sandbox Code Playgroud)