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 -~----------~----~----~----~------~----~------~--~---