Function.prototype.bind behaviour (call vs apply)
Hello everybody.
The currently proposed bind() method for function objects behaves like call(): it takes a number of arguments (from arguments[1] onwards), and uses them for the function execution.
Wouldn't it be more flexible to behave like apply(), taking an array of parameters instead of taking each parameter individually ?
The second approach seems more powerful to me. That is, every call() can easyly be replaced by apply(): func.call( thisObj, a, b, c ) -> func.apply( thisObj, [ a, b, c ] )
...But when you only have got an array of arguments, you can't go the other way around: func.apply( thisObj, argsArray ) -> func.call( /* impossible */ )
Would it be possible to change bind to behave like apply ?
,
Jordan OSETE
On Aug 20, 2009, at 4:33 PM, Jordan Osete wrote:
Hello everybody.
The currently proposed bind() method for function objects behaves
like call(): it takes a number of arguments (from arguments[1]
onwards), and uses them for the function execution.Wouldn't it be more flexible to behave like apply(), taking an array
of parameters instead of taking each parameter individually ?The second approach seems more powerful to me. That is, every call()
can easyly be replaced by apply(): func.call( thisObj, a, b, c ) -> func.apply( thisObj, [ a, b, c ] )...But when you only have got an array of arguments, you can't go
the other way around: func.apply( thisObj, argsArray ) -> func.call( /* impossible */ )Would it be possible to change bind to behave like apply ?
If boundArgs
is an array of arguments to bind, then I think you
should be able to do this via something like:
Function.prototype.bind.apply(targetFn, [thisArg].concat(boundArgs));
// or maybe:
boundArgs.unshift(thisArg); Function.prototype.bind.apply(targetFn, boundArgs);
Which is not very elegant of course (first version also takes a
performance hit by creating unnecessary Array object).
On Aug 21, 2009, at 8:11 PM, Juriy Zaytsev wrote:
If
boundArgs
is an array of arguments to bind, then I think you
should be able to do this via something like:Function.prototype.bind.apply(targetFn, [thisArg].concat(boundArgs));
// or maybe:
boundArgs.unshift(thisArg); Function.prototype.bind.apply(targetFn, boundArgs);
Which is not very elegant of course (first version also takes a
performance hit by creating unnecessary Array object).
But it gets the job done.
I think it's better to leave ES5 Function.prototype.bind as specified,
based on Prototype's bind (and others like it), which take positional
arguments to partially apply.
Then with spread ( doku.php?
id=harmony:spread ) in Harmony, you can write
foo.bind(thisArg, ...argsArray) instead of the above bind.apply
mouthful.
Juriy Zaytsev wrote:
If
boundArgs
is an array of arguments to bind, then I think you should be able to do this via something like:Function.prototype.bind.apply(targetFn, [thisArg].concat(boundArgs));
No offense meant, but I find this quite ugly and not much readable. ;-)
// or maybe:
boundArgs.unshift(thisArg); Function.prototype.bind.apply(targetFn, boundArgs);
Which is not very elegant of course (first version also takes a performance hit by creating unnecessary Array object).
Same thing, and it forces you to alter boundArgs.
Brendan Eich wrote :
But it gets the job done.
I think it's better to leave ES5 Function.prototype.bind as specified, based on Prototype's bind (and others like it), which take positional arguments to partially apply.
Yes, that's what Allen Wirfs-Brock told me, though it wasn't forwarded to the list. I included my reply to his message as an attachment.
Then with spread ( harmony:spread ) in Harmony, you can write foo.bind(thisArg, ...argsArray) instead of the above bind.apply mouthful.
/be
I have to admit spread looks quite exciting to me, unfortunately it won't be widely implemented and usable before long.
The mail I sent to Allen is included as an attachment.
,
Jordan OSETE
Hello everybody.
The currently proposed bind() method for function objects behaves like call(): it takes a number of arguments (from arguments[1] onwards), and uses them for the function execution.
Wouldn't it be more flexible to behave like apply(), taking an array of parameters instead of taking each parameter individually ?
The second approach seems more powerful to me. That is, every call() can easyly be replaced by apply(): func.call( thisObj, a, b, c ) -> func.apply( thisObj, [ a, b, c ] )
...But when you only have got an array of arguments, you can't go the other way around: func.apply( thisObj, argsArray ) -> func.call( /* impossible */ )
Would it be possible to change bind to behave like apply ?
,
Jordan OSETE