3

I came across this piece of code. It didn't look that right to me. Is this the right way to implement super in JavaScript? If not, what is the right way?

function Person(name){
  this.name = name;  
}

function Student(name){
  Person.call(this, name);
}

Student.prototype = new Person(); 
var a = new Student('test');
var b = new Student('test2');
  • 7
    don't implement inheritance in JavaScript - JavaScript gives you arbitrary depth lexical closures so you don't need to use inheritance to share data, data sharing is better done through explicit closure bindings I find. Faking a type system in JavaScript is step #1 towards having tons of runtime bugs in your JavaScript code – Jimmy Hoffa Sep 2 '14 at 16:11
  • 2
    @JimmyHoffa: That is pure opinion without evidence to back it up. Personally, I find closures hard to unit test, thus raising the likelyhood that bugs crop up, negating your argument. The real frustration with object oriented JavaScript in my opinion is that this shifts context depending on how the function was called. – Greg Burghardt Sep 2 '14 at 16:49
  • 3
    @GregBurghardt I agree completely; Yes it's pure opinion, but I enjoy throwing it out there. Also your second issue: I work around it easily by never dealing with this -> just use closures. Yes I recognize they may make unit testing trickier but at that I must say unit testability I find to be more an affect of one's ability to modularize their code into side effect free and referentially transparent portions rather than the approach they use. The more referentially transparent your code, the easier it is to test, often times using inheritance precludes referential transparency though.. – Jimmy Hoffa Sep 2 '14 at 16:57
  • 1
    @JimmyHoffa what you're describing sounds to me like what Crockford calls "functional inheritance". I don't think that pattern deals with the "super" issue any more cleanly than prototypal inheritance, though. As far as I can tell this question is really about referencing the parent explicitly rather than having some kind of super keyword. – Hey Dec 1 '14 at 21:45
  • @Hey what I describe is an approach to get similar benefits to inheritance, but not to use it. I think there should be no prototypal or subtypal inheritance relationships as I find them to be footguns. As I mention above, it is an opinion, and is written in comments because it's not an answer to the asked question. Just a comment to share a different perspective on this problem with folks - one that says: Just don't solve this problem as it's been invented by a faulty solution (subtypal inheritance) to begin with. That's just my opinion – Jimmy Hoffa Dec 1 '14 at 21:55
2

This works and is the right way depending on whether or not the browser supports Object.create:

Student.prototype = Object.create(Person.prototype);

The Object.create method sets up prototypal inheritance without executing the constructor function Person when "inheriting."

1

The first part is pretty common, it's just a way to get the constructor of the subtype to share the functionality of the supertype's constructor. Notice that Person.call doesn't invoke Person as a constructor here, it invokes it as a regular function using the this binding from the Student being constructed.

It's probably a bit more common to see it written like this:

Person.apply(this, arguments);

If you don't like the idea of writing the name of the parent constructor explicitly and are looking for something generic like "super" you could do this instead:

this.constructor.prototype.constructor.apply(this, arguments);

You don't usually see this, though, because it's pretty unwieldy and you probably already have a reference to the parent constructor at the point where you're doing this anyway.


The second part is widely regarded as being incorrect. Don't do this:

Student.prototype = new Person();

Do this instead.

Student.prototype = Object.create(Person.prototype);

Object.create(Person.prototype) gives you an object with Person.prototype in its prototype chain without executing the Person constructor (which could have side effects and is unnecessary).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.