我不问如何使用它。我知道如何使用它。
但是当apply调用调用它的函数时,它究竟是如何将一个参数数组传递给一个未编写为参数的数组的函数?它是否将其给定的arguments数组与被调用的函数" arguments"?
组合在一起我查看了.apply和.call的最新ECMAscript规范,但我并没有真正看到底层逻辑。
欢迎任何解释。我是JavaScript的新手,想要更好地了解幕后发生的事情。我现在正试图自己重新创建一些基本功能,而这个功能给我带来了很多麻烦。
答案 0 :(得分:3)
来自spec。
我们必须采用argArray并创建对象伪数组。
基本上
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
}
我省略了一些发生的类型检查,但这基本上非常接近规范所指示的Function.prototype.apply
如何实现。我们制作自己的对象,并在调用函数之前构建argList
。
重要的是要注意。名为[[Call]]
的内部方法与Function.prototype.call
不同。
答案 1 :(得分:2)
它如何将一个参数数组传递给一个函数,该函数未被编写为参数的数组
你误解了它是如何工作的。 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 :(得分:0)