[英]Why Javascript doesn't let a function redefine itself from within itself?
考慮一下代碼:
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.
基本上我已經嘗試了所有可行的方法,似乎都沒有做到這一點。 有人可以解釋一下原因嗎?
您正在成功重新定義函數,只是調用它的表達式已經抓住了舊函數引用:調用表達式中發生的第一件事是定義要調用的函數的事物被評估,參見第11.2.3節規格:
11.2.3函數調用
生產CallExpression:MemberExpression Arguments的計算方法如下:
- 讓ref成為評估MemberExpression的結果。
- 讓func為GetValue( ref )。
- 設argList是評估Arguments的結果,產生一個參數值的內部列表(見11.2.4)。
- 如果Type( func )不是Object,則拋出TypeError異常。
- 如果IsCallable( func )為false,則拋出TypeError異常。
- 如果Type( ref )是Reference,那么
a)如果IsPropertyReference( ref )為真,那么
一世。 讓thisValue為GetBase( ref )。
b)否則, ref的基礎是環境記錄
一世。 讓thisValue成為調用GetBase( ref )的ImplicitThisValue具體方法的結果。- 否則,Type( ref )不是Reference。
a)讓thisValue不確定。- 返回在func上調用[[Call]]內部方法的結果,提供thisValue作為此值並提供列表argList作為參數值。
在重新定義函數之前發生步驟1和2。
解決方案當然是按照您期望的順序進行操作( 實例 | 源代碼 ):
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)。
JavaScript對運算符參數的評估順序有嚴格的從左到右的規則。 我猜這包括函數調用操作符,這意味着在表達式之前評估第a
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.