(function () { ... }).call(animals[i], i) calls the function (function () { ... }) "on" the object animals[i] (that is: within the scope of the call, this will be animals[i]), with the argument i.
In other words, it's equivalent to this:
animals[i].f = function () { ... };
animals[i].f(i);
except without having to set animals[i].f.
(function () { ... }).call(animals[i], i) calls the function (function () { ... }) "on" the object animals[i] (that is: within the scope of the call, this will be animals[i]), with the argument i.
In other words, it's equivalent to this:
animals[i].f = function () { ... };
animals[i].f(i);
except without having to set animals[i].f.
Perhaps a simpler way to explain it is to collapse it down a bit:
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);
to
(function(i) {...}).call(animals[i], i);
The call could be mistakenly thought to being applied to the animals[i], but it is actually being applied to the anonymous function that has been defined. In other words, the "call" method is being invoked on the anonymous function that was just created. In this way the function is applied to the animals without defining it explicitly.
The difference is that apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly. A useful mnemonic is "A for array and C for comma."
See MDN's documentation on apply and call.
Pseudo syntax:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
There is also, as of ES6, the possibility to spread the array for use with the call function, you can see the compatibilities here.
Sample code:
function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator
K. Scott Allen has a nice writeup on the matter.
Basically, they differ on how they handle function arguments.
The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method."
So:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
Why doesn't it need to be invoked? — because, as you say, it's a reference, and that's all that's desired. The code wants a reference to the function, not a result returned from calling the function.
Is JS 'seeing' the call method chained to slice and then trying to resolve a value to pass to slice from the call(arguments) method? — well I'm not sure what that means. The reference to the
.slice()function is used to get access to the.call()method (inherited from the Function prototype). That function (slice.call) is invoked and passed theargumentsobject as its first parameter. The result is thatslicewill be invoked as if it were called likearguments.slice()— which is not possible directly, as the.slice()function isn't available that way.
Overall, what the code is doing is "borrowing" the .slice() method from the Array prototype and using it as if the arguments object were an array.
Sometimes you'll see that written like this:
return [].slice.call(arguments);
It's a little shorter, and it does the same thing (at the expense of the creation of an otherwise unused array instance).
call in javascript is a way of invoking a method within the function, which hard binds the context of this within a function to the parameter passed to it..For more detail regarding callgo through the link below
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
If you want to know more about this and why call is being used, I highly recommend you to go through this github repo:
https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch1.md
Secondly, by default every regular function expression in JS has an arguments object, which is an iterable which is nothing but the list of parameters passed to that function.
function foo()
{
console.log(arguments); //1,2
}
foo(1,2)
More about arguments
https://www.google.co.in/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=arguments%20in%20javascript
And if you want to learn JS properly, blindly go through this repo:
https://github.com/getify/You-Dont-Know-JS