0

假设我有一个看起来像这样的函数:

var meowLikeACat = function(howoften) { 
    setInterval(function() { 
        alert("meow"); 
    },howoften*1000) 
}

假设我这样称呼它:

var howOften_local = 3;
meowLikeACat(howOften_local+1);

+1该操作实际发生在什么时候?

是否有可能在函数运行之前“拦截”正在传递的数据?

4

2 回答 2

3

+1该操作实际发生在什么时候?

在传递给函数之前,所有参数都会从左到右进行评估。

11.2.3 函数调用

产生式 CallExpression : MemberExpression *Arguments* 评估如下:

  1. ref是评估MemberExpression的结果。
  2. funcGetValue ( ref )。
  3. argList为评估Arguments的结果,生成参数值的内部列表(参见 11.2.4)。
  4. 如果Type ( func ) 不是 Object,则抛出TypeError异常。
  5. 如果IsCallable ( func ) 为false,则抛出TypeError异常。
  6. 如果Type ( ref ) 是Reference,那么
    a. 如果IsPropertyReference ( ref ) 为真,则
        i。让thisValue为 GetBase( ref )。
    湾。否则,ref的基础是环境记录
        i。让thisValue成为调用GetBase ( ref ) 的 ImplicitThisValue 具体方法的结果。
  7. 否则,Type ( ref ) 不是Reference
    一个。让thisValueundefined
  8. 返回在func上调用 [[Call]] 内部方法的结果,提供thisValue作为this值,并提供列表argList作为参数值。

11.2.4 参数列表

参数列表的评估产生一个值列表(见 8.8)。

产生式 Arguments :( )评估如下:

  1. 返回一个空列表。

产生式 Arguments : ( ArgumentList )的评估如下:

  1. 返回评估ArgumentList的结果。

产生式 ArgumentList : AssignmentExpression的评估如下:

  1. ref为评估AssignmentExpression的结果。
  2. argGetValue ( ref )
  3. 返回一个唯一项为arg的列表

产生式 ArgumentList : ArgumentList , AssignmentExpression的评估如下:

  1. 前面的Args 是评估ArgumentList的结果。
  2. ref为评估AssignmentExpression的结果。
  3. argGetValue ( ref )。
  4. 返回一个List,它的长度比 previousArgs 的长度大 1,并且其项是 previousArgs 的项按顺序返回,最后是arg,它是新列表的最后一项。

是否有任何方法可以强制在上述任何情况下进行操作?

前两个是一样的。我看不出如何区分调用函数的时间和将参数传递给函数的时间。

您可以通过传递一个函数来完成第三个:

function meowLikeACat(howoften) {
    setInterval(function() { 
        alert("meow"); 
    }, howoften()*1000) 
}

var howOften_local = 3;
meowLikeACat(function () {
    return howOften_local+1;
});

是否有可能在函数运行之前“拦截”正在传递的数据?

这很简单,如果你的代码假设合作而不是敌意:

function meowLikeACat(howoften) { 
    setInterval(function() { 
        alert("meow"); 
    }, howoften*1000) 
}

function intercept(thisArg, original, before) {
    return function() {
        // could manipulate arguments here,
        // or pass something completely different to original
        before.apply(thisArg, arguments);
        original.apply(thisArg, arguments);
    };
}

function doBefore() {
    console.log('before', arguments);
}

var meowLikeACatIntercepted = intercept(null, meowLikeACat, doBefore);

演示:http: //jsfiddle.net/mattball/e4AY6

于 2013-03-05T03:51:59.273 回答
1

它发生在现场。

var howOften_local = 3;
meowLikeACat(howOften_local+1);

这段代码基本上是这样做的:

meowLikeACat(4);
于 2013-03-05T03:51:53.470 回答