http://dev.rubyonrails.org/browser/spinoffs/prototype/src/base.js contains this definition: Function.prototype.bind = function() { var __method = this, args = $A(arguments), object args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); } } In other words, if a bound function is given the arguments (This,A,B,C) the underlying method has ''this'' bound to the value of This and the underlying method gets the arguments (A,B,C,This,A,B,C) I''ve found no comments indicating why an extra copy of arguments is used. It doesn''t seem like it would be safe to use this extra copy (as it seems like an undocumented feature), and I''m trying to understand why it''s there at all. Is this just hasty code, or is it a workaround for some bug or what? (Or if I''m asking in the wrong place, let me know.) Thanks, -- Raul
On 2/21/06, Miller, Raul D <rdmiller-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote:> In other words, if a bound function is given the arguments > (This,A,B,C) > the underlying method has ''this'' bound to the value of This > and the underlying method gets the arguments > (A,B,C,This,A,B,C)Function.prototype.bind = function() { var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); } } In the bind function itself, ''this'' is a Function. The first parameter to bind is the object that the function will eventually be called on, so this in your bound function will be the object. It took a bit for me to wrap my head around this too, but it''s amazing once you understand it. The arguments aren''t duplicated. The code is structured such that if you give bind() multiple parameters (ie, more than just the object) those extra parameters become parameters for your bound function. Take a look at http://www.brainsick.com/prototype/testbind.html Todd
Todd Ross wrote:> Function.prototype.bind = function() { > var __method = this, args = $A(arguments), object = args.shift(); > return function() { > return __method.apply(object, args.concat($A(arguments))); > } > }...> The arguments aren''t duplicated.Oh, I see. (oops) When ''args= $A(arguments),'' is evaluated, ''arguments'' is a list which has only one element (the function in question). In other words, it''s equivalent to: Function.prototype.bind = function(object) { var __method = this; return function() { return __method.apply(object, arguments); } } Or is there some reason this simpler version would not work? Thanks, -- Raul
I wrote:> which has only one element (the function in question).nit: the object in question. (sorry) -- Raul
On 2/21/06, Miller, Raul D <rdmiller-b1liDLKdkLdWk0Htik3J/w@public.gmane.org> wrote:> Todd Ross wrote: > > Function.prototype.bind = function() { > > var __method = this, args = $A(arguments), object = args.shift(); > > return function() { > > return __method.apply(object, args.concat($A(arguments))); > > } > > } > ... > > The arguments aren''t duplicated. > > Oh, I see. (oops) > > When ''args= $A(arguments),'' is evaluated, ''arguments'' is a list > which has only one element (the function in question).Still not right. ''this'' is the function (as the bind() method is being called on the Function). The first parameter (usually the only) to bind() is the /object/ to call the function on. I think you understand that, but you''re just saying it wrong. func.apply(object, args) works like: object.method = func; object.method(args); delete object.method; (see JavaScript: The Definitive Guide, 4th Edition, Chapter 7.5.4)> In other words, it''s equivalent to: > > Function.prototype.bind = function(object) { > var __method = this; > return function() { > return __method.apply(object, arguments); > } > } > > Or is there some reason this simpler version would not work?That would work except you miss out on the ability to specify ''default'' parameters through the bind() method, although there are no instances of that inside Prototype itself. Todd