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

+1 to that, where you're defining the function inline.  Where you're
not, while this may be faster:

    var self = this;
    handler = function() {
        self.realHandler();
    }

...bind is (for me) much clearer:

    handler = realHandler.bind(this);

But again, yeah, when you're defining the function inline _anyway_,
take advantage of the native closure stuff.

-- T.J. :-)

On Mar 10, 6:44 pm, Ryan Gahl <[email protected]> wrote:
> 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, LLChttp://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 <[email protected]>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" <[email protected]> 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 <[email protected]> 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 [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to