简体   繁体   中英

JavaScript prototypal inheritance confusion - what am I missing here?

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?

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;
}

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, ie each cheesebase object would have its own functions instead of sharing the prototype (and using less memory).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM