2

For a JavaScript project we want to introduce object inheritance to decrease code duplication. However, I cannot quite get it working the way I want and need some help.

We use the module pattern. Suppose there is a super element:

a.namespace('a.elements.Element');
a.elements.Element = (function() {
    // public API -- constructor
    Element = function(properties) {
        this.id = properties.id;
    };

    // public API -- prototype
    Element.prototype = {
        getID: function() {
            return this.id;
        }
    };

    return Element;
}());

And an element inheriting from this super element:

a.namespace('a.elements.SubElement');
a.elements.SubElement = (function() {
    // public API -- constructor
    SubElement = function(properties) {
        // inheritance happens here
        // ???
        this.color = properties.color;
        this.bogus = this.id + 1;
    };

    // public API -- prototype
    SubElement.prototype = {
        getColor: function() {
            return this.color;
        }
    };

    return SubElement;
}());

You will notice that I'm not quite sure how to implement the inheritance itself. In the constructor I have to be able to pass the parameter to the super object constructor and create a super element that is then used to create the inherited one. I need a (comfortable) possibility to access the properties of the super object within the constructor of the new object. Ideally I could operate on the super object as if it was part of the new object.

I also want to be able to create a new SubElement and call getID() on it.

What I want to accomplish seems like the traditional class based inheritance. However, I'd like to do it using prototypal inheritance since that's the JavaScript way. Is that even doable?

Thanks in advance!

EDIT: Fixed usage of private variables as suggested in the comments. EDIT2: Another change of the code: It's important that id is accessible from the constructor of SubElement.

5
  • 1
    Just to let you know: Your "private" variable id will be shared by all instances, so it's rather a static variable. Whenever you create an instance of Element, it will override the current value of id. You cannot use prototype functions and "private" instance variables like this. Commented Jun 25, 2012 at 14:40
  • Module pattern is separate from inheritance and OOP. Also variables trapped inside closures are not private fields of an object. Commented Jun 25, 2012 at 14:44
  • @Esailija: Although they're frequently used as such, per Crockford's pattern. But the closure would have to be the call to the constructor rather than the call to the module factory. :-) Commented Jun 25, 2012 at 14:46
  • @Esailija: :-) Oh, it's not all that bad. Thankfully, though, we'll be getting true private properties in the fullness of time. Commented Jun 25, 2012 at 14:52
  • You're right, of course. I fixed that. Commented Jun 25, 2012 at 15:06

2 Answers 2

1

You can do class-like inheritance using JavaScript's prototypical inheritance if you like. See this other answer for a full example and discussion, which you can easily fit into your pattern.

Sign up to request clarification or add additional context in comments.

5 Comments

Shouldn't this question be closed as a duplicate then?
@FelixKling: I couldn't decide whether it was really a duplicate or not. Different question, basically the same answer. :-) What we need is a canonical "how do you do basic inheritance in JavaScript?" question. Perhaps the one referenced above is close enough...
Yes, we definitely need one. I have the feeling I write about inheritance every second day. Your answer seems to cover everything.
+1 to even you out, though could probably be closed as duplicate.
Was exactly what I needed. I guess, I didn't find the answer since I didn't really know what I was looking for. Thanks!
1

Try this code (the inherit method is taken from here):

function inherit(proto) {
  function F() {};     
  F.prototype = proto;
  return new F();
}

a.namespace('a.elements.SubElement');
a.elements.SubElement = (function() {
    // private properties
    var color;

    // public API -- constructor
    SubElement = function(properties) {
        color = properties.color;
    };

    //inherit from parent
    SubElement.prototype = inherit(a.elements.Element);

    //add new methods to the prototype

    SubElement.prototype.getColor = function() {
            return color;
    }

    SubElement.prototype.doSomethinkWithID = function() {
            var id = this.getID();
    }

    return SubElement;
}());

1 Comment

Thanks for the suggestion. However, the problem is, that I cannot access the properties of the super element within the constructor of SubElement which I need to. I have fixed my code to state that more clearly. Sorry about that.

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.