admin管理员组文章数量:1334911
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?
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?
Share Improve this question asked Jan 6, 2012 at 21:12 jaketrentjaketrent 1,17311 silver badges25 bronze badges 1- not sure what you're trying to point out, i started out a jsfiddle for it, but could you plete it with your actuall issues with the underscore's bind method? jsfiddle/saelfaer/7fCbT – Sander Commented Jan 7, 2012 at 0:04
4 Answers
Reset to default 3Why 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
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()
.
I patched Backbone with getConstructor(), which returns the constructor and is immune to _.bindAll.
Usage:
this.getConstructor().__super__;
Implementation:
(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;
})();
I'm new to Backbone but have over 4 years experience with another framework that also expects you to pass an object containing methods to an extend method, but the problem is this does not give sufficiently fine-grained control to act upon the methods contained within the object being passed.
To gain more control you can instead pass a closure to extend, and the closure can return an object. This technique in general allows finer-grained control and more potential for sophistication, and can be leveraged to solve your specific issue.
Inside the closure that returns the methods, those methods can be split into two broad categories:
- Backbone-specific, e.g. constructor & initialize
- Custom, specific to your application
If we return the custom methods specific to our application from their own separate object, we can then use _.bind for "partial application" of _.bindAll to just those custom method names.
Putting it all together then:
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's possible to "mixin" these methods from another file
function modelMethods() {
return {
foo: function() {},
bar: function() {},
}
}
}());
本文标签: javascriptWhy is my BackboneViewconstructorsuper undefined if I use bindAll(this)Stack Overflow
版权声明:本文标题:javascript - Why is my Backbone.View.constructor.__super__ undefined if I use _.bindAll(this) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742324119a2453380.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论