1

somehow JS inheritance doesn't get in my head. I tried quite a few things now and for some reason I cannot add a method to an object that inherits.

See my try of defining B.setC that then is not available later somehow. Any hints?

cheers Tom

A = function( value){
        this.aValue = value;
}


B = function(value){
    A.call(this, value); 
    this.bValue=value+value;
}

B.prototype = Object.create(A.prototype);//subclass extends superclass


B.setC = function(value){
    this.c = value+value+value;
    console.log("execution");
}

B.prototype.setD = function(value){
    this.D = value+value+value+value;
    console.log("execution");
}





 x = new B("ConstructorParam");
x.setC("methodParam");// gives that setC is not a function
x.setD("methodParam");// works but I added setD to A not B
3
  • 3
    It's just a typo, you meant B.prototype.setC = ..., but you have B.setC = ... Commented Sep 11, 2016 at 16:58
  • Actually it isn't a typo. I want to add setC to B not A and if my understanding is right and to what I saw debugging in Chrome it is if I use B.prototype.setB then I add setB to the prototype of B aka A and not B . Or am I missing sth? Commented Sep 11, 2016 at 17:01
  • Your code is also falling prey to The Horror of Implicit Globals (that's a post on my blog): Declare your variables. Commented Sep 11, 2016 at 17:16

1 Answer 1

3

The confusion seems to come from this misunderstanding; quoting your comment:

Actually it isn't a typo. I want to add setC to B not A and if my understanding is right and to what I saw debugging in Chrome it is if I use B.prototype.setB then I add setB to the prototype of B aka A and not B . Or am I missing sth?

which is also shown by this comment in the question:

x.setD("methodParam");// works but I added setD to A not B

B.prototype is not A. B.prototype is an object that has A.prototype as its prototype. You correctly added setD to B.prototype; it isn't in any way added to either A or A.prototype.

If you want to use setC and setD the way you showed, you would put them either on B.prototype (so they are accessible on instances of B) or on A.prototype (so they're accessible on instances of A or B).

If we change B.setC = to B.prototype.setC =, make d lower case to match c, add some missing vars, and use shorter values when creating and calling the methods, we get this:

var A = function( value){
    this.aValue = value;
};

var B = function(value){
    A.call(this, value); 
    this.bValue = value + value;
};

B.prototype = Object.create(A.prototype);//subclass extends superclass

B.setC = function(value){
    this.c = value + value + value;
    console.log("execution");
};

B.prototype.setD = function(value){
    this.d = value + value + value + value;
    console.log("execution");
};

var x = new B("b");
x.setC("c");
x.setD("d");

Just after the last line of code, this is what we have in memory (minus a bunch of unnecessary details):

         +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
         |                                                               |
         \ +−−−−−−−−−−−−−−−+                                             |
A−−−−−−−−−>|   function    |                                             |
           +−−−−−−−−−−−−−−−+                             +−−−−−−−−−−−−−+ |
           | prototype     |−−−−−−−−−−−−−−−−−−−−−−−−−−−−>|   object    | |    
           +−−−−−−−−−−−−−−−+                           / +−−−−−−−−−−−−−+ |    
                                                       | | constructor |−+
                                                       | +−−−−−−−−−−−−−+
         +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |
         |                                           | |
         \ +−−−−−−−−−−−−−−−+                         | |
B−−−−−−−−−>|   function    |                         | |
           +−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−−+ | |
           | prototype     |−−−>|      object      | | |
           +−−−−−−−−−−−−−−−+  / +−−−−−−−−−−−−−−−−−−+ | |
                              | | constructor      |−+ |
                              | | setC: (function) |   |
                              | | setD: (function) |   |
                              | | [[Prototype]]    |−−−+
           +−−−−−−−−−−−−−−−+  | +−−−−−−−−−−−−−−−−−−+
x−−−−−−−−−>|    object     |  |
           +−−−−−−−−−−−−−−−+  |
           | aValue: "a"   |  |
           | bValue: "aa"  |  |
           | c: "ccc"      |  |
           | d: "dddd"     |  |
           | [[Prototype]] |−−+
           +−−−−−−−−−−−−−−−+ 

[[Prototype]] above is the name the spec uses for the "internal slot" of an object that contains its reference to its prototype object. In contrast, prototype, the property on functions (e.g., A.prototype), is just a normal property of functions that points to the object that new will use as the [[Prototype]] of the new object it creates if you use that function with new.


Just for completeness, here that is in ES2015+:

class A {
    constructor(value) {
        this.aValue = value;
    }
}

class B extends A {
    constructor(value) {
        super(value); 
        this.bValue = value + value;
    }

    setC(value) {
        this.c = value + value + value;
        console.log("execution");
    }

    setD(value) {
        this.d = value + value + value + value;
        console.log("execution");
    }
}

let x = new B("b");
x.setC("c");
x.setD("d");
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.