JavaScript 原型继承混乱 - 我在这里错过了什么?

发布于 2024-12-16 12:05:50 字数 210 浏览 1 评论 0原文

我正在努力解决一个我以前认为我理解的主题 - 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

油焖大侠 2024-12-23 12:05:50

当您调用 new CheeseBase() 时,this 的值是您在“cheddar()”内部用作原型的对象,而不是“切达干酪”的实例。因此,“saySomething()”函数总是说“all Cheese”,因为它引用了从构造函数调用中“捕获的”this

如果您将“saySomething()”更改为在“alert()”调用中引用“this.favoriteCheese”,则会在弹出窗口中显示“cheddar”。

如果您确实希望子类修改基础对象,或者,您可以重新排列:

function cheesebase() {

    var that = this;

    this.favouriteCheese = "all cheese";

    this.setBaseCheese = function(chz) {
      that.favouriteCheese = chz;
    };

    this.saySomething = function() {
        alert("My favourite cheese is " + that.favouriteCheese);
    };
}

function cheddar() {

    var returnObject = Object.create(new cheesebase());

    returnObject.setBaseCheese("cheddar");

    returnObject.saySomethingElse = function() {
        alert("I like cheese");
    };

    return returnObject;
}

The value of this when you call new 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:

function cheesebase() {

    var that = this;

    this.favouriteCheese = "all cheese";

    this.setBaseCheese = function(chz) {
      that.favouriteCheese = chz;
    };

    this.saySomething = function() {
        alert("My favourite cheese is " + that.favouriteCheese);
    };
}

function cheddar() {

    var returnObject = Object.create(new cheesebase());

    returnObject.setBaseCheese("cheddar");

    returnObject.saySomethingElse = function() {
        alert("I like cheese");
    };

    return returnObject;
}
梦幻的心爱 2024-12-23 12:05:50

我最好的猜测是,以下代码导致了问题。

var that = this; 

我的原始直觉(没有参考 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.

var that = this; 

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 inside cheeseBase 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 have this pointing to actual prototype, stores this pointer inside that and creates closure around that, which is prototype object.

And, during execution of cheeseBase binding of this changes to actual object instance.

I guess something like this, can be found under this binding in JS spec.

猫瑾少女 2024-12-23 12:05:50

也许你想要实现的是这样的: 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. each cheesebase object would have its own functions instead of sharing the prototype (and using less memory).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文