Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Function: Applying Apply

Tags:

javascript

I got stumped by this weirdness.

Let's say I have this array:

var array = [{
  something: 'special'
}, 'and', 'a', 'bunch', 'of', 'parameters'];

Could I apply the apply method of a function to invoke the function with the this object being {something: 'special'} and the parameters being the rest of array?

In other words, could I do this

var tester = function() {
  console.log('this,', this);
  console.log('args,', arguments);
};
tester.apply.apply(tester, array);

And expect the output to be the following?

> this, {"something": "special"}
> args, {"0": "and", "1": "a", "2": "bunch", "3": "of", "4": "parameters"}

I tried it.

TypeError: Function.prototype.apply: Arguments list has wrong type

But why? It seems like this should work.

like image 217
skeggse Avatar asked Jul 16 '13 20:07

skeggse


1 Answers

But why?

Let's reduce your calls step-by-step:

tester.apply.apply(tester, array) // resolves to
(Function.prototype.apply).apply(tester, array) // does a
tester.apply({something: 'special'}, 'and', 'a', 'bunch', 'of', 'parameters');

Here you can see what's going wrong. Correct would be

var array = [
    {something: 'special'},
    ['and', 'a', 'bunch', 'of', 'parameters']
];

then the apply.apply(tester, array) would become

tester.apply({something: 'special'}, ['and', 'a', 'bunch', 'of', 'parameters']);

which does a

tester.call({something: 'special'}, 'and', 'a', 'bunch', 'of', 'parameters');

So with your original array you'd need to use

(Function.prototype.call).apply(tester, array)
like image 190
Bergi Avatar answered Oct 01 '22 20:10

Bergi