I won't speak to your .bind() mods as I've not reviewed them, but in
general, for the majority case of simply binding the context of a function
to an object in order to fix the "this" keyword within the function, it is
ALWAYS just easier and MUCH MUCH faster to "early bind" to a variable
outside the function, and use that variable within the closure instead of
"this". Then you have zero performance or memory issues, and debugging is
unhindered by the convoluted chain of methods that results from overuse of
.bind().

E.g., instead of:

var someHandlerFunction = function(blah) {
this.doSomething(blah);
}.bind(this);


Do this... (always):

var me = this;
var someHandlerFunction = function(blah) {
me.doSomething(blah);
};

I do agree there are just times when .bind() is called for, but I am fairly
certain the majority of people WAY overuse it.

When in a class where I would otherwise be doing a bunch of binding, I just
create the "var me = this;" variable at the top of whatever scope I'm
currently in.

Ryan Gahl
CEO
Nth Penguin, LLC
http://www.nthpenguin.com
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl


On Tue, Mar 10, 2009 at 1:19 PM, Tobie Langel <tobie.lan...@gmail.com>wrote:

>
> Robert, have you looked at the implementation in trunk ?
>
> I rewrote most of it not long ago after serious benchmarking and
> taking into consideration smart(er) memory management.
>
> This kind of discussion belongs ont the core mailing list BTW, to make
> sure no one misses it!
>
> Best,
>
> Tobie
>
>
>
> On Mar 10, 6:49 pm, "T.J. Crowder" <t...@crowdersoftware.com> wrote:
> > Hi,
> >
> > On the face of it, I like the thought of skipping the arguments prep
> > in the no-args case, but have you done any profiling to be sure that
> > it really has a measurable benefit?  Same question on inlining the per-
> > call arguments concatenation...  Without a solid, measurable benefit,
> > I'd avoid the additional complexity.  You can deal with the debugger
> > thing like this:
> >
> > Replace Prototype's original:
> >
> >     return __method.apply(object, args.concat($A(arguments)));
> >
> > with:
> >
> >     var newargs = args.concat($A(arguments));
> >     return __method.apply(object, newargs);
> >
> > Re: unbind.  That version repeatedly unbinds until it finds a non-
> > bound function, which means it's not the reciprocal of bind.  E.g.:
> >
> >     x = foo.bind(obj, 1);
> >     y = x.bind(obj, 2);
> >     y.unbind() === x ?
> >     // -> false, the unbind returns foo, not x
> >
> > From the name, I'd expect unbind to be the reciprocal of bind.  Since
> > it's mostly a debug function, it may be worth just using a different
> > name.
> >
> > FWIW,
> > --
> > T.J. Crowder
> > tj / crowder software / com
> > Independent Software Engineer, consulting services available
> >
> > On Mar 10, 4:41 pm, Robert Kieffer <bro...@gmail.com> wrote:
> >
> > > As I suspect is common with many Prototype shops, over here at
> > > Zenbe.com, we're making HEAVY use of Function#bind().  We've been
> > > using a custom version of the bind() method for a while now, and I've
> > > recently added a couple enhancements  that I'd like to get people's
> > > opinions on - especially that of the Prototype team.
> >
> > > I've attached a commented version of our implementation below (we run
> > > this after importing the Prototype library, so it just overwrites the
> > > Prototype code).  The motivation for this implementation is as
> > > follows:
> >
> > > - bind() is so ubiquitous for us that performance is a top priority.
> > > We're willing to have a bit more code here to make things run faster.
> > > In particular, 99% of our use of bind() is simply to bind a function
> > > to an object, without binding any arguments (e.g. "...bind
> > > (someObject)").  So special-casing that situation makes sense.
> >
> > > - Stepping through bound functions is painful because you constantly
> > > have to step-into/out-of the $A method.  It's possible to improve
> > > performance *and* make stepping through code easier by inlining the
> > > code that sets up the args array.
> >
> > > - Inspecting functions created by bind() (e.g. "someFunction.toString
> > > ()") is never helpful.  Provide a way to "unbind" a function to get at
> > > the original method.
> >
> > > Aside from the obvious increase in code size (which isn't *that* much
> > > when the code is compacted - adds ~100-150 bytes), are there any
> > > disadvantages/weaknesses to this implementation?  Would it make sense
> > > to migrate some or all of these changes into the Prototype codebase?
> >
> > > =======================
> > >   Object.extend(Function.prototype, {
> > >     bind: function(object) {
> > >       var __method = this, __f;
> > >       // Special case: No args or object being bound - just return
> > > this function
> > >       if (arguments.length < 2 && arguments[0] === undefined) return
> > > this;
> >
> > >       if (arguments.length == 1) {
> > >         // Special case: No args are being bound - don't bother
> > > creating a new
> > >         // args structure
> > >         __f = function() {
> > >           return __method.apply(object, arguments);
> > >         };
> > >       } else {
> > >         // General case: Basically do what the native Prototype
> > > implementation
> > >         // does, but be as as efficient as possible, and make it
> > > trivial to
> > >         // step through in a debugger.
> > >         var args = $A(arguments), l = args.length-1;
> > >         args.shift();
> > >         __f = function() {
> > >           // Set up the args array.  Note that we recycle the args
> > > array,
> > >           // rather than creating a new one.  Also do all this on ONE
> > > line so
> > >           // it only takes one click to step over in a debugger.
> > >           var ll = arguments.length; args.length = l + ll; while
> > > (ll--) args[l+ll] = arguments[ll];
> > >           return __method.apply(object, args);
> > >         };
> > >       }
> >
> > >       // Finally, keep a reference to the original function so we can
> > >       // unbind() (below) as needed.
> > >       __f._boundFunction = this;
> > >       return __f;
> > >     },
> >
> > >     unbind: function() {
> > >       var orig = this;
> > >       while (orig._boundFunction) orig = orig._boundFunction;
> > >       return orig;
> > >     }
> > >   });
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to