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

I will subclass my own Backbone.View. If in the initialization function of a super class I write:

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

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

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

But, if in a superclass I use:

_.bindAll(this)

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

this.constructor.__super__

- undefined. Any wisdom is why this is so?

+5
source share
4 answers

Why not just use this to call super:

(I split several lines for clarification, you can make a call in one line)

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

Link: GetPrototypeOf

+3
source

, , , ...

Underscore bindAll (), , , .

constructor, Backbone ( __super__), . , object.constructor __super__.

, Underscore 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;
}

Underscore, _.extend().

+2

Backbone getConstructor(), _.bindAll.

:

this.getConstructor().__super__;

:

(function() {
  var backboneExtend = Backbone.Model.extend;
  var constructorExtend = function() {
    var child = backboneExtend.apply(this, arguments);
    child.prototype.getConstructor = function() {
      return child;
    };
    return child;
  };
  Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = constructorExtend;
})();
+1

Backbone, 4- , , , , , , , , .

, , . .

Inside a closure that returns methods, these methods can be divided into two broad categories:

  • Specific to the baseline, for example. constructor and initialize
  • Custom, specific to your application.

If we return custom methods specific to our application from our separate object, we can use _.bind for the "partial application" _.bindAll only for these custom method names.

Putting it all together:

var foobar = Backbone.Model.extend(function() {
    var foobarMethods = modelMethods();

    return _.extend({}, foobarMethods, {
        constructor: function() {
            _.bind(_.bindAll, this, _.keys(foobarMethods));
            // equivalent to _.bindAll(this, 'foo', 'bar') except that the above
            // allow methods to be arbitrarily added or removed
        },
        initialize : function() {}          
    });

    //It possible to "mixin" these methods from another file
    function modelMethods() {
        return {
            foo: function() {},
            bar: function() {},
        }
    }
}());
0
source

All Articles