Function.prototype.bind behaviour (call vs apply)

# Jordan Osete (16 years ago)

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

# Jordan Osete (16 years ago)

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

# Juriy Zaytsev (16 years ago)

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).

# Brendan Eich (16 years ago)

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.

# Jordan Osete (16 years ago)

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