2012-03-30 62 views
5

考虑代码:为什么Javascript不会让函数本身重新定义自己?

window.a = function(x){ 
     var r = x*2; 
     window.a =alert; // redefines itself after first call 
     return r; 
    }; 
    a('2 * 2 = '+a(2)); // doesn't work. it should've alerted "2 * 2 = 4" 

这不起作用或者:

window.a = function(x){ 
     alert(x); 
     window.a = function(x){ // redefines itself after first call 
      var r = x*2; 
      return r; 
     } 
    }; 
    a('2 * 2 = '+a(2)); // doesn't work. it should've alerted "2 * 2 = 4" 

既不做到这一点:

window.a = function(x){ alert(x); window.c = window.a; window.a = window.b; window.b = window.c; }; 
    window.b = function(x){ var r = x*2; window.c = window.b; window.b = window.a; window.a = window.c; return r; }; 
    a('2 * 2 = '+a(2)); // doesn't work. 

,基本上我已经尝试了所有可能的方式也不似乎做的工作。有人可以解释为什么吗?

+1

出于好奇,你为什么要这么做? – maialithar 2012-03-30 11:07:35

+0

嗯,第一个实际上适用于我(Chrome 18) – Yoshi 2012-03-30 11:10:28

+0

在Chrome和IE中工作得很好... – 2012-03-30 11:11:21

回答

8

成功地重新定义函数,它只是表达调用它已经抓住了老函数的引用:这种情况发生在呼叫表达的东西定义调用评估什么功能的第一件事情,看本说明书的Section 11.2.3

11.2.3函数调用

生产CallExpression:MemberExpression参数被评估小号如下:

  1. 裁判是评估MemberExpression的结果。
  2. func成为GetValue(ref)。
  3. argList是评估参数的结果,生成参数值的内部列表(参见11.2.4)。
  4. 如果类型(func)不是Object,则抛出TypeError异常。
  5. 如果IsCallable(func)为false,则引发TypeError异常。
  6. 如果Type(REF)是参考,然后
        a)如果IsPropertyReference(REF)为真,则
               我。假设thisValue是GetBase(参考号)。
        b)中否则,REF的碱是环境记录
               我。假设thisValue是调用GetBase的ImplicitThisValue具体方法(ref)的结果。
  7. 其他类型(参考号)不是参考。
    a)让这个值为未定义。
  8. 返回调用FUNC的[[调用]]内部方法,提供thisValue作为该值,并提供所述列表ARGLIST作为参数值的结果。

步骤1和2发生在函数重新定义之前。

的解决方法当然是让事情在你期望的顺序发生(live example | source):

window.a = function(x){ 
    var r = x*2; 
    window.a =alert; // redefines itself after first call 
    return r; 
}; 
var val = a(2); 
a('2 * 2 = '+ val); 

边注:有趣的是your first example作品在Chrome(V8)(也在IE6的JScript版本中工作;但是,JScript有批次的问题)。它不应该工作,并且不在Firefox(SpiderMonkey),Opera(Carakan)或IE9(Chakra)中。

1

对于操作符参数的评估顺序,JavaScript有严格的从左到右的规则。我猜测这包括函数调用操作符,这意味着在表达式之前评估第一个a

相关问题