Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript call parent function from child object

I am new to Object Oriented Programming with javascript. And trying to implement the basics that we know from other programming languages.

I have two classes, one parent and one child. Parent have some private functions and some public functions. Child will inherit parent class.

And I wish to access parent public function from child object. What I am trying to do:

function SuperClass {
    //Constructor implementation of this class

    //public functions
    return {
        parentPublicFunction: function() {
            //Public function implementation
        }
    }
    function privateFunction() {
        //Private function implementation.
    }
}

//Inheriting
childClass.prototype = Object.create(SuperClass.prototype);
childClass.prototype.constructor = childClass;
childClass.prototype.parent = SuperClass.prototype;
function childClass {
    //Call to super constructor
    this.parent.constructor.call(this, arguments);

    //Public function for childClass.
    return {
        childPublicFunction: function() {
            //function implementation
        }
    }
}

var childObj = new childClass();
childObj.parentPublicFunction();

I am getting this error when running this:

Uncaught TypeError: undefined is not a function

Am I doing something which is incorrect.? Thanks in advance!

like image 842
Veer Shrivastav Avatar asked Aug 28 '26 23:08

Veer Shrivastav


1 Answers

JavaScript OOP does not work like Java's or C#, don't expect it to, and do not try to make it. The only thing that will result from so doing is misunderstandings. Instead of trying to force your old paradigms on a language that is built up entirely different, rather learn how JavaScript OOP works.

JavaScript is Object Oriented, but that doesn't mean it has classes. At least not in the way most developers coming from Java or similar languages think of classes. It does not have classical inheritance either. However, all of these can be "faked", or mimicked (which is what you're effectively trying to do). The problem with so doing, is the fact that developers coming from Java or similar see code that looks like classes and classical inheritance, so they think it's classes with classical inheritance, and expect it to behave as such, whereas it might end up working completely different.

Let's start with your SuperClass function (because that's what it is. It's a function, not a class). First of all, your code isn't even valid syntax, because your SuperClass function does not parenthesizes. The correct syntax would be function SuperClass() { ... }.

Secondly, JavaScript uses prototypes to handle inheritance between objects (not classes), and if you want to do prototypical inheritance (which some of your code suggest you want to), you can't return a new, anonymous object from the SuperClass function. Allow me to illustrate a bit what goes on here.

When you call your SuperClass function (either from the childClass function, or from any other place) using the new keyword, as in var inst = new SuperClass();, what effectively happens is the following:

  1. JavaScript creates a new blank object, which prototype is equal to the prototype-property on the function you're calling. In code this would be var temp = Object.create(SuperClass.prototype);.
  2. JavaScript calls your function with that object as the this object. In code this would be SuperClass.call(temp, <arguments>).
  3. If the function returns anything, inst is set to that value, else, it's set to the temp value.

Now, in your SuperClass function you do the following:

//Constructor implementation of this class

//public functions
return {
    parentPublicFunction: function() {
        //Public function implementation
    }
}
function privateFunction() {
    //Private function implementation.
}

What happens here is that your SuperClass method get's invoked with a this, which is an instance of SuperClass, ie. it has SuperClass.prototype in it's prototype chain. This would mean that if you for instance did this instanceof SuperClass, you would get true, as you would expect. Then you go and return a new, anonymous object, which has a property named parentPublicFunction (which just happens to be a function, but could be anything). This new object you return, is not an instance ofSuperClass. It does not have SuperClass.prototype in it's property. You've created a situation where if I do (new SuperClass()) instanceof SuperClass you get false. In other word, the instance you return from your SuperClass constructor function, does not implement your "class". This is probably not at all what you intended, which is one of the reasons you cannot just strap classical inheritance principles on JavaScript and expect things to function the same.

Now, what we have so far, is a function name SuperClass, which returns an Object without any relation to SuperClass. SuperClass has a prototype which is empty, meaning that even if you did somehow manage to create objects with SuperClass.prototype in it's prototype chain, it would not inherit anything from SuperClass, because there is nothing defined to inherit. Which brings us to the childClass function.

First off all, I'll be naming it ChildClass instead of childClass. Any function in JavaScript you expect people to call with new should start with an upper case. Any function you don't expect to be called with new should be started with a lower case. There is no way in JavaScript to know if a function is intended to be called with or without new, so this is used to signify.

Now, ChildClass.prototype is set up as a instance of SuperClass, meaning that any methods in SuperClass's prototype will be callable from an instance of ChildClass. And any instance of ChildClass is also an instance of SuperClass (just as you'd expect). However, as already explained, the prototype of SuperClass is empty, so there is nothing to inherit from it. Therefore, the only thing ChildClass gains from this inheritance is the fact that a instanceof ChildClass implies that a instanceof SuperClass. However, just as with SuperClass, you return a anonymous object from ChildClass, which again result in the fact that (new ChildClass()) instanceof ChildClass is false.

And therein, lies (most) of your problems. The solution is simply to learn how OOP works in JavaScript and embrace that when doing JavaScript, instead of trying to bend it to how you assume things to work.

like image 180
Alxandr Avatar answered Aug 31 '26 14:08

Alxandr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!