2

This is sort of a follow up of from this question: Python like inheritance for JavaScript

But I phrased it wrong and made it seem like I wanted classical inheritance in JavaScript when I just wanted to figure out how to do it similarly to Python.

This is what I have so far but it isn't working as I would like it to.

var util = require("util")

function FirstClass() {
    this.name = "First Class";
}

FirstClass.prototype.sayName = function(){
    this.callFunction("some_function", "hello")
}

FirstClass.prototype.callFunction = function(){
    var func = arguments[0]; 
    var args = Array.prototype.slice.call(arguments).slice(1, arguments.length)  
    if (this[func] !== undefined){ 
        this[func].apply(null, args); 
    } 
}

function SubClass(){}
util.inherits(SubClass, FirstClass)
SubClass.prototype.some_function = function(msg){
    console.log(msg, this.name) // "hello undefined"
}

var sub_class = new SubClass();
sub_class.sayName();

When I try sub_class.sayName() It calls correctly and inherited sayName right, but when I try using the this keyword to show the name it doesn't work and prints undefined next to 'hello', so how would I fix it so it will show 'hello FirstClass'?

I was thinking this have all the variables and objects that FirstClass has since it inherits from it but it doesn't. Is that how prototypal inheritance is suppose to work? If so is there any way I can view/change parent variables from the child class?

I've tried looking up prototypal inheritance for JavaScript to figure it out but I'm not quite grasping the concept since I'm use to classical inheritance. Does anyone know how to inherit from the parent class and change it's variables from a child class?

Also if anyone has a good link to look at so I can understand prototypal inheritance better for future references that would be great.

Community
  • 1
  • 1
user3234209
  • 935
  • 2
  • 8
  • 14
  • 1
    I'd be interested in knowing the answer to this question as well. I've worked with prototypes, just not with inheritances yet. – kemicofa ghost Jun 12 '14 at 19:29
  • @Grimbode: When you work with prototypes, you're doing inheritance. – cookie monster Jun 12 '14 at 19:30
  • @cookie monster, then what is the use of inherits()? – kemicofa ghost Jun 12 '14 at 19:31
  • 1
    It's just a helper function that abstracts away a little boilerplate code when making the prototype object of one function inherit from another. https://github.com/joyent/node/blob/master/lib/util.js#L628-L638 But irrespective of how you set up a prototype chain, when you add a member to an object used as the prototype of another, the other object inherits that property. – cookie monster Jun 12 '14 at 19:37

3 Answers3

4

You are missing this part:

function SubClass(){
   FirstClass.apply(this);
}

This would be the equivalent to a super invocation in traditional class inheritance.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
2

Your problem lies here: this[func].apply(null, args);

It should read: this[func].apply(this, args);

cookie monster
  • 10,671
  • 4
  • 31
  • 45
Tony Nardi
  • 413
  • 2
  • 7
1

Here is a simplified example of how to inherit and extend a class. I very highly recommend checking Javascript Design Patterns for much better examples of how to create Classes with inheritance.

Now, as I was not familiar with what util was supposed to be doing, this example demonstrates how to achieve the result with native JS and no helpers:

JSFiddle here: http://jsfiddle.net/YAj5R/

function FirstClass() {
    this.name = "First Class";
}

FirstClass.prototype.sayName = function () {
    this.callFunction("some_function", "hello")
}

FirstClass.prototype.callFunction = function () {
    var func = arguments[0];
    var args = Array.prototype.slice.call(arguments).slice(1, arguments.length)
    if (this[func] !== undefined) {
        this[func].apply(this, args);
    }
}

function SubClass() {
    var parent = new FirstClass();

    // this is lightweight example of an "extend" method
    for(var attr in parent) {
        // if this subclass has not over-written an attr,
        // copy the attributes of FirstClass to SubClass
        if(!this[attr]) {
            this[attr] = parent[attr];
        }
    }

    return this;
}

SubClass.prototype.some_function = function (msg) {
    console.log(msg, this.name);
}

var sub_class = new SubClass();
sub_class.sayName();
kcent
  • 939
  • 7
  • 8
  • 1
    This approach, though, might fail to define any non-enumerable attributes in `FirstClass`. – Edwin Dalorzo Jun 12 '14 at 21:12
  • @user3234209: You won't want to do it this way in practice. It defeats the point of using prototypal inheritance in the first place where you don't need the `for(var attr in parent) {` at all, and changes made to `FirstClass.prototype` won't be seen on the `SubClass` objects. The `util.inherits` can mostly be replaced with two short lines of code. – cookie monster Jun 12 '14 at 21:12