【问题标题】:hasOwnProperty is traversing the prototype chainhasOwnProperty 正在遍历原型链
【发布时间】:2019-09-30 10:56:54
【问题描述】:

今天我注意到hasOwnProperty 方法的一些奇怪行为。

我在完全支持 ES6 类的环境中,所以不用担心转译。

上面的代码 sn-p 应该分别返回 true 和 false,但它都返回 true。

class Stuff {
  constructor() { this.something = 'something'; }
}
class MoreStuff extends Stuff {}
const stuff = new Stuff();
const moreStuff = new MoreStuff();

console.log(Object.prototype.hasOwnProperty.call(stuff, 'something'));
console.log(Object.prototype.hasOwnProperty.call(moreStuff, 'something'));

也许我在这里遗漏了一些东西,但只要我知道,东西上存在一些东西,它在 moreStuff 上被继承,但似乎两者都存在。 我错过了什么?

【问题讨论】:

  • 你为什么使用callObject.prototype.hasOwnProperty 通常在类而不是实例上调用。
  • @evolutionxbox 不,倒退;它在实例上调用,如stuff.hasOwnProperty("something")
  • @Pointy 感谢您的澄清。在任何情况下您会使用callhasOwnProperty
  • 好吧,我想不出有什么理由这样做。我不能肯定地说它从不有意义,但通常情况涉及对象引用,因此直接使用它同样容易。
  • 在几种情况下,您不能依赖具有该方法的对象。 Object.create(null)undefinednull 是尝试直接调用该方法时会抛出的示例。

标签: javascript


【解决方案1】:

Stuff 构造函数将“something”属性直接放在构造的对象上。无论您是创建父类的实例还是继承类的实例,这都是正确的。不涉及原型链。

【讨论】:

    【解决方案2】:

    当您在您的构造函数中执行以下操作时:

    this.something = 'something';
    

    您是将该值放入对象而不是原型中。

    即使是子类,构造函数也会将'something' 的值添加到对象中。

    如果你想在原型上使用它,那么它必须是静态的:

    class Stuff {
      static get something() {
        return 'something';
      }
      
      constructor() {
        this.ownProp = true;
      }
    }
    Stuff.somethingElse = 'somethingElse';
    
    class MoreStuff extends Stuff {}
    const stuff = new Stuff();
    const moreStuff = new MoreStuff();
    
    console.log(stuff.hasOwnProperty('something'));
    console.log(stuff.hasOwnProperty('somethingElse'));
    console.log(stuff.hasOwnProperty('ownProp'));
    console.log(moreStuff.hasOwnProperty('something'));
    console.log(moreStuff.hasOwnProperty('somethingElse'));
    console.log(moreStuff.hasOwnProperty('ownProp'));

    ownProp 仍然是实例的属性,其中 somethingsomethingElse 是类(原型)的属性

    【讨论】:

    • 所以没有办法将普通的“属性”添加到只属于每个实例的类中。在构造函数上添加的所有内容都是实例道具。仅适用于方法。我不是很担心,但很高兴知道。作为原型继承的超级粉丝,很遗憾我自己没有弄清楚这一点。
    • 如果你将你的属性作为类的一部分(一个静态值),那么它对类的所有实例都是可用的。
    • 我不清楚,抱歉。我的意思是没有办法让一个属性在类的实例上成为ownProperty,而不是在扩展类上成为自己的属性。静态属性总是属于原型,而不是实例,老实说这是有道理的。
    • 对不起,我误会了。是的,你是对的。它要么是实例上的ownProperty,要么是类定义上的ownProperty。如果类有一个静态的,然后你也在实例上设置一个值,它可以是两者,但我怀疑这是你想要的。
    猜你喜欢
    • 1970-01-01
    • 2012-04-18
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 2023-03-25
    • 2017-09-03
    相关资源
    最近更新 更多