JavaScript 原型继承混乱 - 我在这里错过了什么?
我正在努力解决一个我以前认为我理解的主题 - JavaScript 中的原型继承。
我有一个 jsfiddle 概述了我的问题这里
我有一个基础对象和一个继承实现。我希望实现对基础的属性进行更改,并让基础访问这些更新的属性。
谁能指出我哪里错了?
I am struggling with a subject I previously thought I understood - prototypal inheritance in JavaScript.
I have a jsfiddle which outlines my problem here
I have a base object and an inheriting implementation. I want the implementation to make changes to the base's properties, and for the base to access these updated properties.
Can anyone please point out where I'm going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您调用
new CheeseBase()
时,this
的值是您在“cheddar()”内部用作原型的对象,而不是“切达干酪”的实例。因此,“saySomething()”函数总是说“all Cheese”,因为它引用了从构造函数调用中“捕获的”this
。如果您将“saySomething()”更改为在“alert()”调用中引用“this.favoriteCheese”,则会在弹出窗口中显示“cheddar”。
如果您确实希望子类修改基础对象,或者,您可以重新排列:
The value of
this
when you callnew cheeseBase()
is the object you're using as the prototype from inside "cheddar()", and not the instance of "cheddar". Thus, the "saySomething()" function always says "all cheese" because it refers to the "captured"this
from the constructor call.If you change "saySomething()" to reference "this.favoriteCheese" in the "alert()" call, it says "cheddar" in the popup.
If you really want the subclass to be modifying the base object, alternatively, you could rearrange:
我最好的猜测是,以下代码导致了问题。
我的原始直觉(没有参考 JS 规范),基于原型的继承是基于原型对象的单个实例,而不复制该对象。
因此,cheeseBase 中的 this 指针指向原型对象,它永远不应该改变。
后代方法和属性绑定,在寻找方法或属性时迭代 [this, this.prototype, this.prototype.prototype, ...] 序列,其中每个原型都意味着是不可变的单例对象。
鉴于此,cheeseBase 构造函数让
this
指向实际原型,将 this 指针存储在that
中,并在that
周围创建闭包,这是原型对象。并且,在执行
cheeseBase
期间,this
绑定会更改为实际对象实例。我想类似的东西可以在 JS 规范的 this 绑定下找到。
My best guess, that following code causes the problem.
My raw intuition (without reference to JS specification), it that prototype based inheritance is based on single instance of prototype object, without copying of this object.
So,
this
pointer insidecheeseBase
points to prototype object, that should never change.Descendants method and property binding, iterates over [this, this.prototype, this.prototype.prototype, ...] sequence while seeking method or property, where each prototype a meant to be immutable singleton object.
Given this,
cheeseBase
constructor havethis
pointing to actual prototype, stores this pointer insidethat
and creates closure aroundthat
, which is prototype object.And, during execution of
cheeseBase
binding ofthis
changes to actual object instance.I guess something like this, can be found under this binding in JS spec.
也许你想要实现的是这样的: http://jsfiddle.net/yrU6y/1/
无论如何,在您的原始示例中,您没有使用基础对象的原型。这意味着每次创建新的 cheesebase 时,您都会重新定义其函数,即每个 cheesebase 对象都有自己的函数,而不是共享原型(并且使用更少的内存) 。
Maybe what you want to achieve is this: http://jsfiddle.net/yrU6y/1/
Anyway, in your original example you are not using the prototype of the base object. This would mean that everytime you created a new
cheesebase
you would redefine its functions, i.e. eachcheesebase
object would have its own functions instead of sharing the prototype (and using less memory).