This pattern, which is a spin from the module pattern, allows many nice things, including the use of truly private, class level, (static, protected, etc) members. If you want to REALLY maximize performance and minimize the overhead of the grossly overused .bind() function, you can identify instance methods that really could be "private static" methods and move them into the class module's "global" area, passing in the instance reference instead of binding (thus, moving more towards functional looking code, but I still tend to think of it as OO, where these become private static members of the class).
To mashup kangax's pattern here with what I'm saying, and aim to just not use bind if you don't have to (which is a Good Thing)... consider the following slightly altered take(s) on kangax's code...
var Widget = Class.create((function() {
//protected, static methods
function init(widget) {
widget.element.observe('click', onClick);
//note, instead of using "bind" (which creates a copy of a function anyway), we simply create the method in our desired scope (imagine that!)
function onClick() {
// ... now "widget" is the instance reference to use in here
}
}
return {
initialize: function(id) {
this.element = $(id);
init(this);
}
}
})());
...and yet another variation is to use the constructor as the place to, you know... construct. I left the init() method at the static level for illustration.
var Widget = Class.create((function() {
//protected, static methods
function init(config) {
config.widget.element.observe('click', config.onClickHandler);
}
return {
initialize: function(id) {
//early bind during construction:
var me = this;
//public properties...
this.element = $(id);
//private instance level methods... (replacement technique for using .bind())
function onClick() {
// ... now "me" is the instance reference to use in here
}
//use the static init method, passing in our instance level onClick handler (and of course the instance itself)...
init({
widget: this,
onClickHandler: onClick
});
}
}
})());
You'll notice that this pattern accomplishes several things. For starters, it hides methods that really shouldn't be exposed as a public interface on the instances anyway. The "say that it's private in the comments or by adding an underscore in front of it" technique is just lazy and Bad Form. It also avoids the overhead of using .bind() - which as you've discovered adds up quickly. The true purpose of .bind() is just to create a copy of a function, applied to the object you pass in. It is VERY convenient, and easy to use (and mis-use). However, just creating the copy of your method in the scope in which it is needed is all you have to do (no need for the cleverness). Then, no $A() overhead, and debugging is straight forward, AND you can truly hide members from calling code as appropriate... so while you're seeming to move towards more functional code you're also actually reaping _more_ of the benefits of OO.
It's a shift in thinking, but one that you'll grow to love if you make the investment.
Ryan Gahl
CEO
Nth Penguin, LLC
http://www.nthpenguin.com
--
Inquire:
1-920-574-2218Blog:
http://www.someElement.com
LinkedIn Profile:
http://www.linkedin.com/in/ryangahl