Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my Backbone.View.constructor.__super__ undefined if I use _.bindAll(this)

I am subclassing my own Backbone.View. If, in the super class' initialize function, I write:

_.bindAll(this, 'many', 'methods');

And specify the methods that I want to bind to this context, I can call super from the subclass via:

this.constructor.__super__.initialize.apply(this, arguments);

But, if in the super class, I use:

_.bindAll(this)

instead, when I go to call super from my subclass,

this.constructor.__super__

is undefined. Any wisdom on why that is?

like image 524
jaketrent Avatar asked Jan 06 '12 21:01

jaketrent


2 Answers

Why not simply use this to call the super:

(I am separating to several lines for clarification, you can do the call in one line)

var thisProto = Object.getPrototypeOf(thisInstance);
var superProto = Object.getPrototypeOf(thisProto);
superProto.superMethod.apply(thisInstance, [param1, param2]);

Reference: GetPrototypeOf

like image 145
Danny R Avatar answered Oct 10 '22 00:10

Danny R


Seeing as there's only solutions to this problem but not explanations, I'm going to attempt to supply one...

When Underscore's bindAll method is invoked with the single argument (the object), all function type properties of that object no longer reference the original function but instead another that fixes the context.

Since one of the object's properties of type function is constructor, which is a reference to the Backbone constructor function (with the property __super__), the property will be overwritten with a new function. This then means that object.constructor will no longer have a property __super__.

To work around this issue I used the following function as an alternative to Underscore's bindAll:

function safeBindAll(obj) {
    var funcs = Array.prototype.slice.call(arguments, 1);

    if (funcs.length == 0) {
        funcs = _.functions(obj);
    }

    _.each(funcs, function(f) {
        var oldProps = obj[f];
        obj[f] = _.bind(obj[f], obj);

        _.extend(obj[f], oldProps);
    });

    return obj;
}

It's almost identical to Underscore's version but adds any properties of the original function to the new function through use of _.extend().

like image 41
Ed . Avatar answered Oct 10 '22 00:10

Ed .