I'm not asking how to use it. I know how to use it.
But when apply invokes the function that called it, how exactly does it pass an array of arguments into a function that was not written to take an array for an argument? Does it combine its given arguments array with the called functions "arguments"?
I looked at the latest ECMAscript specifications for .apply and .call, but I didn't really see anything about underlying logic.
Any explanation would be welcome. I'm new to JavaScript, and want to better understand what's going on under the hood. I'm currently trying to recreate some of the basic functions on my own, and this one is giving me a lot of trouble.
The Difference Between call() and apply() The difference is: The call() method takes arguments separately. The apply() method takes arguments as an array. The apply() method is very handy if you want to use an array instead of an argument list.
We use the Bind() method to call a function with the this value, this keyword refers to the same object which is currently selected . In other words, bind() method allows us to easily set which object will be bound by the this keyword when a function or method is invoked.
In JavaScript, you can use call() , apply() , and bind() methods to couple a function with an object. This way you can call the function on the object as if it belonged to it. The call() and apply() are very similar methods. They both execute the bound function on the object immediately.
It's an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it's created. It has nothing to do with any event-handler for any events (such as document. onload ). Consider the part within the first pair of parentheses: (function(){})(); ....it is a regular function expression.
From the spec.
We have to take the argArray and create what will be the arguments object pseudo array.
Essentially
Function.prototype.apply = function apply (thisArg, argArray) {
var len = argArray.length;
var n = ToUint32(len);
var argList = []; // where this is a List not an array.
var index = 0;
var indexName;
var nextArg;
while (index < len) {
indexName = ToString(index);
nextArg = argArray[indexName];
argList.push(nextArg);
index++;
}
return this['[[Call]]'](func, thisArg, argList); // ignore the syntax however
// This is the line where the function
// will be called and provide
// the thisArg and thisArray
}
I omitted some of the type checking that happens but this is essentially pretty close to what the spec dictates as how Function.prototype.apply
is implemented. We craft our own object and build up the argList
prior to calling the function.
Its important to note. that the internal method named [[Call]]
is different than Function.prototype.call
.
how exactly does it pass an array of arguments into a function that was not written to take an array for an argument
You are misunderstanding how this works. apply
does not pass an array of arguments to the object. It takes an array and then uses that to dynamically build a function call, similarly to what you could do with an eval
statement (but it does it natively).
For example, an eval
statement could work like this:
function buildFromArray(funcName, arrayOfArgs)
{
var functionCall = funcName + "(";
for ( var i = 0; i < arrayOfArgs.length; i++ )
{
//Very simplified, only allows for string args
functionCall += "\"" + arrayOfArgs + "\"";
if ( i < arrayOfArgs.length - 1 ) functionCall += ",";
}
functionCall += ")";
//Now we run the compiled call which will be something like:
//myFunction("one","two")
eval( functionCall );
}
buildFromArray( "myFunction", [ "one", "two" ] );
This is very simplified, but you can see how an array is never passed to the function myFunction
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With