为什么Javascript不让一个函数从内部重新定义自己? [英] Why Javascript doesn't let a function redefine itself from within itself?

查看:115
本文介绍了为什么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. 

基本上我已经尝试了所有可能的方法,似乎都没有做到这一点。有人可以解释一下原因吗?

And basically I've tried all possible ways and neither seem to do the job. Can someone please explain why?

推荐答案

成功重新定义了这个功能,它只是表达式调用它已经抓住了旧的函数引用:调用表达式中发生的第一件事是定义要调用的函数的事物被评估,参见第11.2.3节

You are successfully redefining the function, it's just that the expression calling it has already grabbed the old function reference: The first thing that happens in a call expression is that the thing defining what function to call is evaluated, see Section 11.2.3 of the specification:


11.2.3函数调用

生产 CallExpression:MemberExpression Arguments 的计算方法如下:


  1. ref 成为评估 MemberExpression 的结果。

  2. func 是GetValue( ref )。

  3. argList 成为评估 Arguments 的结果,生成参数值的内部列表(见11.2.4)。

  4. 如果Type( func )是n ot Object,抛出TypeError异常。

  5. 如果IsCallable( func )为false,则抛出TypeError异常。

  6. 如果Type( ref )是Reference,那么

       a)如果IsPropertyReference( ref )为true,那么
    < BR>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;我。让 thisValue 为GetBase( ref )。

       b)否则, ref 的基础是环境记录

           i 。让 thisValue 成为调用GetBase的ImplicitThisValue具体方法的结果( ref )。

  7. 否则,输入( ref )不是参考。

    a)让 thisValue 未定义。

  8. 返回在 func上调用[[Call]]内部方法的结果,提供 thisValue 作为此值,并提供列表 argList 作为参数值。

  1. Let ref be the result of evaluating MemberExpression.
  2. Let func be GetValue(ref).
  3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).
  4. If Type(func) is not Object, throw a TypeError exception.
  5. If IsCallable(func) is false, throw a TypeError exception.
  6. If Type(ref) is Reference, then
      a) If IsPropertyReference(ref) is true, then
          i. Let thisValue be GetBase(ref).
      b) Else, the base of ref is an Environment Record
          i. Let thisValue be the result of calling the ImplicitThisValue concrete method of GetBase(ref).
  7. Else, Type(ref) is not Reference.
    a) Let thisValue be undefined.
  8. Return the result of calling the [[Call]] internal method on func, providing thisValue as the this value and providing the list argList as the argument values.


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

Steps 1 and 2 occur before the function is redefined.

解决方案当然是制造东西按照您期望的顺序发生(实例 | 来源):

The solution is of course to make things happen in the order you expect (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);






附注:有趣的是你的第一个例子适用于Chrome(V8)(它也适用于IE6的JScript版本;但是,JScript有很多的问题)。它应该不起作用,并且不适用于Firefox(SpiderMonkey),Opera(Carakan)或IE9(Chakra)。


Side note: It's interesting that your first example works in Chrome (V8) (it also works in IE6's version of JScript; but then, JScript had lots of issues). It shouldn't work, and doesn't in Firefox (SpiderMonkey), Opera (Carakan), or IE9 (Chakra).

这篇关于为什么Javascript不让一个函数从内部重新定义自己?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆