Skip to content


put __super__ on the prototype #787

wants to merge 1 commit into from

Been doing research on extending Backbone and found this interesting bit:

// Set a convenience property in case the parent's prototype is needed later.
child.__super__ = parent.prototype;

At an initial glance it looks as if it could work this this.__super__.someMethod, but in reality you must call it off the constructor which is assigned directly above.

This patch instead places __super__ on the prototype.

/* One level of extension, calling Backbone.Model.prototype.initialize */

// Current;

// New;

// Manually;

I figure there must be an intentional reason for why its currently set up the way it is. Any elaboration would be great.


Yes __super__ is not intended for you to use it directly, as the underscored name implies.

It's the internal property that CoffeeScript uses to make super() work efficiently, and should not be an enumerable property on the prototype. In JavaScript, you should use the manual style:;

The existence of __super__ in Backbone is our one line concession so that you can write:

Model = Backbone.Model.extend

  set: (attrs, options) ->

... and have it work.

@jashkenas jashkenas closed this

One thing I was thinking of to be fair to the JavaScript users is doing:

child.prototype.super = parent.prototype;

So the JavaScript'ers could do:;

Unfortunately, Backbone isn't trying to be a JavaScript OOP library ... we're not providing "special" super() semantics in general. This means that in JavaScript, you should be using the standard pattern:, arg);

If we did want to be an OOP library -- we would be providing much more sugar than this.


I propose the creation of a wiki page on CoffeeScript which targets the "How to write coffeescript-compatible libraries in Javascript"


Yes, that would make a fine wiki page, but let's be clear: Every JavaScript library is compatible with CoffeeScript -- this is simply a convenience so that super() can be used, even when you're not using the class keyword (which you could also use). A special case.


Funny, I never fully understood prototypical inheritance until I used Backbone...but I see people are still running away into their comfort zone.


+1. Why not give regular JS users the convenience instead of just CS users? Part of backbone's elegance is extending views, collections, etc. and calling the "super" method is part of the territory.


While @jashkenas said

Yes __super__ is not intended for you to use it directly, as the underscored name implies.

IMHO it's a super legit use of __super__. But that should be used only when you don't know what your super class is. If you know it you should call it directly.


Just my two cents: "no fair" that Backbone adds special code to support super in CoffeeScript but not regular JavaScript when both could be just as easily done. It's cool that Backbone doesn't want to add lots of OOP support, but supporting this one minor thing in JS as well as CS would be much appreciated. Otherwise having an object that extends multiple methods is error-prone and tedious to refactor when the parent class name changes.

Model = Backbone.Model.extend

  set: (attrs, options) ->

Doesn't actually work with coffeeScript, it will output the following javascript, which will throw a reference error on set is not defined

var Model;
Model = Backbone.Model.extend({
  set: function(attrs, options) {
    return, doesntworkactually);

@tonyxiao I believe what @jashkenas meant was something like the following...?

Model = Bakbone.Model.extend()
Model::set = ->
  # ...

which compiles to

var Model;

Model = Backbone.Model.extend();

Model.prototype.set = function() {
  return Model.__super__.set.apply(this, arguments);

What about

class Model extends Backbone.Model
  set: ->


I ended up implementing an invokeSuper() method yesterday which can be used from Backbone hierarchies of classes.

  method: function() {
    // do something

It's usable as a mixin, see the code here:


After reading a few articles on this subject, I ended up going with something like this

(function(Backbone, _) {

    // Extend Backbone Classes with a 'super' function to execute a method of an instance's superclass
    _.each(['Collection', 'Model', 'View', 'Router'], function(className) {
        Backbone[className].prototype.super = function(funcName) {
            var parentPrototype = this.constructor.__super__;
            if (parentPrototype && typeof parentPrototype[funcName] === 'function') {
                return this.constructor.__super__[funcName].apply(this,;

})(Backbone, _);

And then invoking it like:

var Account = SomeCustomCollection.extend({
      initialize: function() {

Sucks that you have to pass in the method name as an argument, but I like it otherwise.


For those of use wanting this bit of OOP sugar, this looks promising:


@dstibrany: good concise code, but YUI compressor fails because of 'super'. Using '_super' works.

Backbone[className].prototype._super = function(funcName) { ...


No guys, it's not a good idea to use such a "super" method.

Let me expose it:

var Root = Backbone.Model.extend({
  log: function (msg) {

var Screamer = Root.extend({
  log: function (msg) {, msg + '!');

var SuperScreamer = Screamer.extend({
  log: function (msg) {, 'OH MY GOD, '+msg);

var aSuperScreamer = new SuperScreamer();

aSuperScreamer.log('Hallo world'); // ERROR: Maximum call stack exceeded.

Why? Because Screamer.prototype.log calls this.constructor.__super__ which is Screamer.prototype ;)


Just for clarification, if you want to use __super__, use it as follows:, 'OH MY GOD, '+msg);



Sorry, I forgot to put the good pattern alongside!


ES6 Classes are almost out, bringing the built-in ability to call super() inside a class method. :+1:

@rochoa rochoa referenced this pull request in CartoDB/cartodb.js

🔥 backbone elder #957

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 14, 2011
  1. @tbranyen

    put __super__ on the prototype

    tbranyen committed
Showing with 1 addition and 1 deletion.
  1. +1 −1 backbone.js
2 backbone.js
@@ -1133,7 +1133,7 @@
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed later.
- child.__super__ = parent.prototype;
+ child.prototype.__super__ = parent.prototype;
return child;
Something went wrong with that request. Please try again.