【问题标题】:Why does an object keep its inherited property?为什么对象保留其继承的属性?
【发布时间】:2021-04-04 08:31:53
【问题描述】:
function Dog(name){
    this.name=name;
}
let dogA=new Dog('Paul');
 
Dog.prototype.eat=true;
dogA.eat; //true

现在我销毁 Dog.prototype,为什么 dogA.eat 还在那里?

Dog.prototype=null;
dogA.eat;// Still true?

我在想 dogA.eat 继承自 Dog.prototype。现在Dog.prototype 不见了。 dogA.eat怎么还存在?

【问题讨论】:

  • Dog.prototype = null; 不会“破坏”原型,它只是将prototype 属性重新分配给其他东西,就像在let a = {}; const b = a; 中一样,a = null; 不会影响b,不会改变对象,也不会破坏任何东西。原来的对象还在。
  • 由于原型现在是别的东西,仍然感到困惑,为什么原型链没有破坏?
  • JavaScript Prototype - Please ClarifyUnderstanding the difference between Object.create() and new SomeFunction()。另见How value to __proto__ is assigned in javascript?Dog.prototype = null; 只影响 构造的对象。这种重新分配永远不会触及现有对象的原型。 spec 更详细地回答了所有这些问题。
  • delete Dog.prototype.eat 将删除该属性。分配 null 会影响新对象。
  • 是的,我现在明白了。这里的关键概念是原始的Dog.prototype 总是像普通对象一样存在。而dogA.__proto__ 一直指向对象的内存位置。现在Dog.prototype 指向新内存位置中的null(例如,再次初始化),但dogA.__proto__ 仍然指向旧内存位置,所以eat 仍然是true。故事结束。

标签: javascript


【解决方案1】:

属性eat 存储在dogA.__proto__ 中。当您使用new 运算符创建dogADog 实例时,javascript 将执行dogA.__proto__ = Dog.prototype = someObject。现在你生成Dog.prototype = null,但dogA.__proto__ 仍然等于someObject。所以dogA.eat 仍然是true。如果您创建dogA.__proto__ = null,那么dogA.eat 将是undefined

【讨论】:

  • 谢谢。 Thought eat 存储在 Dog.prototype...
【解决方案2】:

要销毁原型链,需要使用Object.setPrototypeOf(dogA, null)

清空Dog.prototype 只会影响new Dog 创建的新实例,而不影响Object.getPrototypeOf(dogA),它仍然是具有eat 属性的对象。

【讨论】:

    【解决方案3】:

    好吧,在被卡住了几天之后,我意识到它基本上与原型无关。都是关于指针和内存的。

    Dog.prototype的原始内存存储eat:true。然后Dog.prototype 被重新初始化并指向一个存储null 的新内存。另一方面,dogA.__proto__ 始终指向包含eat:true 的原始内存。所以Dog.prototype的重新初始化不会影响dogA.__proto__,因为它们最终在不同的内存位置。

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      相关资源
      最近更新 更多