按照V8票,它說,因爲它是在現實世界 使用JavaScript和尾調用
尾調用消除不兼容JavaScript。考慮以下幾點:
function foo(x) {
return bar(x + 1);
}
function bar(x) {
return foo.arguments[0];
}
foo(1)
這將返回1.
它沒有解釋清楚,如果JavaScript支持尾調用,這將是什麼富(1)爲什麼值?
任何人都可以解釋一下嗎?
按照V8票,它說,因爲它是在現實世界 使用JavaScript和尾調用
尾調用消除不兼容JavaScript。考慮以下幾點:
function foo(x) {
return bar(x + 1);
}
function bar(x) {
return foo.arguments[0];
}
foo(1)
這將返回1.
它沒有解釋清楚,如果JavaScript支持尾調用,這將是什麼富(1)爲什麼值?
任何人都可以解釋一下嗎?
It didn't explain clearly what if JavaScript support tail call, what would be the value of foo(1) and why?
值將1
當你做foo(1)
因爲foo
函數返回bar
功能和bar
函數的結果也不過是讀foo
功能與foo.arguments[0]
第一個參數(arguments
是隱含可用對象的每一個功能,用於讀取傳遞給函數的參數)並返回它。的foo
第一個參數恰好是1
當你這樣做:
foo(1);
這裏是擊穿:
function foo(x) {
return bar(x + 1); // foo calls bar function which returns 1
}
function bar(x) {
return foo.arguments[0]; // bar reads first argument passed to foo which is 1
}
foo(1); // 1 is x in foo function
的bar
函數只是讀取foo
第一個參數(通過foo.arguments[0]
)並返回,因爲其中沒有添加完成。
這值得一點解釋。談話開始像這樣(格式化代碼):
If I open the JavaScript console in Chrome and write this:
function fac(n, a) { if (n == 0) { return a; } else { return fac(n - 1, a * n); } } fac(100000, 1);
I get this: RangeError: Maximum call stack size exceeded
I think V8 might be a nice target virtual machine for other programming languages if it supported tail calls. It's the only big obstacle I can see for languages with functional features.
如果你測試代碼,你會發現,fac
作品低值,返回Infinity
更高的價值,並導致瀏覽器拋出一個RangeError
(最大通話堆棧大小超過),甚至更高的值。
其原因是從另一個函數中調用的每個函數都被添加到「調用堆棧」中,這涉及一些內存開銷。有了足夠的遞歸,環境就會耗盡內存。
這是通過「tail call elimination」在其他語言中工作,或者不需要將調用添加到調用堆棧。例如,類似於函數的東西可以存在與普通函數不同的地方,因爲它們在返回時會導致調用函數返回。這可以消除添加到調用堆棧的需要,這意味着遞歸本質上可以是無限的。請參閱Wikipedia上的tail call文章以獲得深入解釋。
對上述消息的響應只是爲什麼tail-call消除(將函數從調用堆棧中刪除)與其他功能(Function#arguments)
不兼容的原因提供的,這些功能可以是非標準功能。
爲了清楚起見,tail call elimination是一種節省堆棧空間的優化技術,對於遞歸尤其有用。當函數以另一個函數調用結束時,尾部調用消除可以避免分配另一個棧幀來調用被調用的函數。相反,它會重用(銷燬和重新調用)調用函數的堆棧幀,因爲它(可能)不再需要。但是,該示例顯示JavaScript代碼可能仍需要調用者的堆棧框架。
It didn't explain clearly what if JavaScript support tail call, what would be the value of foo(1) and why?
如果尾調用消除了支持,對foo
調用的信息將使得尾部調用bar
時遭到破壞,因此foo.arguments[0]
將是一個錯誤。如果給定的代碼正常工作,則尾部呼叫消除是不可能的。
等等,那有效?哇。 – Ryan 2012-02-25 17:49:33
僅供參考,http://markmail.org/message/tzlbsdo2tvxy7q4f – 2012-02-25 18:06:04