0

MDN 的 setTimer 页面上,有一个小的 shim / 兼容层 setTimer 可以让 Internet Explorer 接受 setTimer 方法中的其他参数,这些参数将传递给回调。

我非常了解下面的所有代码:

if (document.all && !window.setTimeout.isPolyfill) {
  var __nativeST__ = window.setTimeout;
  window.setTimeout = function (
                          vCallback, 
                          nDelay /*, 
                          argumentToPass1, 
                          argumentToPass2, etc. */
                          ) {
    var aArgs = Array.prototype.slice.call(arguments, 2);
    return __nativeST__(vCallback instanceof Function ? function () {
      vCallback.apply(null, aArgs);
    } : vCallback, nDelay);
  };
  window.setTimeout.isPolyfill = true;
}

除了一行:

var aArgs = Array.prototype.slice.call(arguments, 2);

它引用arguments了 ,但我看不到该名称在此行之前的任何地方被引用。它也不在保留字列表中,所以它似乎没有任何魔法。为了让我理解它,它必须以某种方式引用被覆盖的 setTimeout 函数的参数,然后用于slice()获取前两个参数之后的每个参数。

4

3 回答 3

1

arguments确实是魔法;它是一个非常类似于包含传递给当前函数的参数的数组的对象。该对象在所有函数中都具有局部作用域。

由于它不完全是一个数组,因此该模式Array.prototype.slice.call(arguments)通常用于将多个(或所有)参数值提取到一个实数数组中。在这种特定情况下,aArgs最终成为一个数组,其中包含setTimeout除了前两个之外传递给替换的所有参数。

于 2013-01-24T09:45:26.697 回答
1

arguments 神奇 - 它是以数组形式传递给函数的参数。

请参阅MDN 上的参数: “与传递给函数 [...] 在所有函数中可用的参数相对应的类数组对象”

于 2013-01-24T09:45:53.350 回答
1

该对象arguments包含所有传递给函数的参数,包括那些未在函数声明中命名的参数。

请记住,假设以下函数

function doStuf( param1 ) { /* do something */ }

打这样的电话也是有效的

doStuff( 'stuff', 'morestuff', 2, 'evenmorestuff' );

arguments在这种情况下,您可以使用该对象引用所有参数。


因此,在您的特定代码中,以下行

var aArgs = Array.prototype.slice.call(arguments, 2);

复制传递给 shim 函数的所有参数,但前两个。然而,前两个被明确命名并被引用为(vCallbacknDelay)。

于 2013-01-24T09:49:14.040 回答