【发布时间】:2019-07-10 19:23:00
【问题描述】:
我正在尝试理解 Javascript 原型继承,但无法理解对象实例与其各自类的原型属性之间的关系,该原型属性存储继承的方法。
我了解在类的原型属性中定义方法允许实例访问/继承这些方法,这样就不会重新定义方法。大概这是通过允许实例指向内存中的方法的指针(或类似的东西)来实现的。我也理解为什么向类的原型属性添加方法允许先前创建的实例访问这些“新”方法,因为实例只是访问它们的原型属性(包括它们派生的类),而原型属性又访问类的原型属性。
我不理解的是以下场景:
-
我用方法定义了一个平凡的对象:
function Person(name) { this.name = name; } Person.prototype.greeting = function() { return "Hello, " + this.name; } -
我创建了一个实例并且可以访问数据:
var p = new Person("Ryan"); p.name //"Ryan" p.greeting() //"Hello, Ryan" -
我重新定义人没有问候:
Person = function (name) { this.name = name; } -
我仍然可以使用上一个实例的问候语:
p.greeting() //"Hello, Ryan" but expected error
如果 Person 被重新定义,它会覆盖内存中先前的 Person 构造函数,如果不再有任何与 Person 关联的此类方法,实例“p”如何仍然可以访问 greeting 方法?实例实际上是在它们自己的原型字段中复制其继承类方法的位置吗?如果是这样的话,如果实例直接将这些方法的位置存储在自己的原型字段中,为什么总是谈论处理器必须“走上”才能找到继承方法的“原型链”?
非常感谢您的帮助。如果我错过了一些简单的事情,我深表歉意。
【问题讨论】:
-
您只是在创建一个新类(并覆盖变量
Person),但您不会更改p是其实例的类或其继承的原型。 -
@Bergi 这作为对正在发生的事情的描述是有道理的,但我不明白为什么相同的内存区域没有被覆盖 - 我想这是对象和此类数据特有的功能因为 JS 开发人员预计会重写函数,所以类型?因为如果我将一个整数分配给一个变量并重新分配该变量,那么内存中的相同位置将被使用,不是吗?还是上面的函数的原始位置没有被重写,因为仍然有一个指向它的活动指针,所以新请求的内存超出了内存的限制?
-
JS 中的对象没有固定的位置,不能覆盖。该变量仅包含对内存中某处的对象(或函数对象,在这种情况下)的引用。创建新函数会在其他地方分配新内存,分配给变量只会更改存储在该变量中的引用。其他东西(比如你的
p实例)仍然引用旧对象。 JavaScript 是一种面向对象的垃圾回收语言。
标签: javascript object javascript-objects