为什么 属性 在对象实例化后定义的不是自己的 属性

why property defined after object's instantiation is not an own property

在这里,我创建了一个父实例 class 并在对象本身上定义了一个名为 smile 的 属性。我知道构造函数原型上定义的 属性 不是对象自己的 属性 。但是为什么 "smile" 属性 没有通过 for in 循环内部的 hasOwnProperty 测试?

function Parent(){
   this.name='parent';
}
Parent.prototype.age='34';

var p=new Parent();
p.smile='nice';  // not an own property ?
console.log(p);
for(var prop in p){
  if(Object.hasOwnProperty(prop)){
       console.log(prop);  // prints only "name"
   }
}

您在滥用 Object.prototype.hasOwnProperty()。上述函数将以测试对象作为其上下文调用,这意味着您应该执行 p.hasOwnProperty(prop) 而不是 Object.hasOwnProperty(prop)。然后你会得到你期待的结果。

hasOwnProperty 是在 Object.prototype 上定义的,这意味着大多数对象(您手动将原型设置为 null 的对象除外)将继承该方法,因此它可以在他们身上调用。 p就是这样一个对象。它的原型链没有什么异常,按照上面的描述改一下应该就可以了。

现在您可能会问为什么您的代码不会在 if 语句行上抛出错误。那是因为 Object 是一个函数,因此最终继承自 Object.prototype.

if (Object.hasOwnProperty(prop)) {

检查 Object 是否为给定名称的 属性。 Object.name 存在于 Object 函数中,这就是为什么它 returns true.

想要的是p.hasOwnProperty(prop),这样您就可以检查实例本身是否具有属性,而不是从原型继承。但是,如果实例有一个名为 hasOwnProperty 的 属性,以这种方式调用函数会导致问题,因此通常会看到以下扩展形式:

Object.prototype.hasOwnProperty.call(p, prop)