How does the JavaScript.apply method work?

I do not ask how to use it. I know how to use it.

But when apply calls the function it calls, how exactly does it pass an array of arguments to a function that was not written to accept the array for the argument? Does it combine its array of arguments with the called arguments function?

I looked at the latest ECMAscript specifications for .apply and .call, but I did not see anything about the underlying logic.

Any explanation would be appreciated. I am new to JavaScript and want to better understand what is happening under the hood. I am currently trying to recreate some basic functions myself, and this causes a lot of problems.

+4
source share
3 answers

From spec .

We need to take argArray and create what will be the argument to the 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 skipped some of the type checks that occur, but this is essentially pretty close to what the specification specifies as implemented Function.prototype.apply. We create our own object and create argListbefore calling the function.

It is important to note. that the internal method named [[Call]]differs from Function.prototype.call.

+3
source

how exactly does it pass an array of arguments to a function that was not written to accept an array for the argument

, . apply . , , , eval ( ).

, eval :

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" ] );

, , myFunction.

+2

Function.prototype.apply : JavaScript-. , , , C * API, , . API, Function.prototype.apply .


" " Function.prototype.apply Function.prototype.toString V8

* Suppose the JS engine is written in C. Replace with any language <insert JS engine here> written in.

0
source

Source: https://habr.com/ru/post/1624371/


All Articles