JS的函數(shù)調(diào)用棧stack size的計算方法
如果你寫了一個一直調(diào)用自身的死循環(huán),那么恭喜你,很快就可以看到報錯:Uncaught RangeError: Maximum call stack size exceeded。那么這個call stack size有多少呢?
1. 計算方法
如下的方法可以為你計算出你使用的JavaScript引擎可以支持多深的調(diào)用(由Ben Alman的一段代碼獲得靈感):
function computeMaxCallStackSize() {
try {
return 1 + computeMaxCallStackSize();
} catch (e) {
// Call stack overflow
return 1;
}
}
運行得到如下三個結(jié)果:
- Node.js: 11034
- Firefox: 50994
- Chrome: 10402
這些數(shù)字代表了什么呢?Mr.Aleph告訴我在V8,可調(diào)用的層數(shù)基于兩個方面:1. 棧的大?。?. 每一棧幀的大小(用于記錄函數(shù)參數(shù)和局部變量)。你可以在computeMaxCallStackSize聲明局部變量來測試,你會發(fā)現(xiàn)數(shù)字變小。
2. ECMAScript 6中尾遞歸優(yōu)化
ECMAScript 6支持尾遞歸優(yōu)化:如果一個函數(shù)的最后一個操作是函數(shù)調(diào)用,那么將會用“跳轉(zhuǎn)”而不是“子調(diào)用”。也就是說如果你將computeMaxCallStackSize重寫成如下形式,在ES6的嚴(yán)格模式下,就會一直運行了。
function computeMaxCallStackSize(size) {
size = size || 1;
return computeMaxCallStackSize(size + 1);
}
3. 亮點評論
Andrei: “ECMAScript 6”版本的代碼根本跑不通。雖然size會被更改,但是最終并沒有值返回。
回復(fù)Andrei: 有趣!你不能用這段代碼去計算stack size。在ES6下,這段代碼會一直運行,因此不會返回數(shù)據(jù)。在其它情況下,會返回RangeError。為了使其工作,我把代碼重寫了一下:
var computeMaxCallStackSize = (function() {
return function() {
var size = 0;
function cs() {
try {
size++;
return cs();
} catch(e) {
return size + 1;
}
}
return cs();
};
}());
相關(guān)文章
微信小程序+mqtt,esp8266溫濕度讀取的實現(xiàn)方法
這篇文章主要介紹了微信小程序+mqtt,esp8266溫濕度讀取的實現(xiàn)方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
深入理解基于vue-cli的webpack打包優(yōu)化實踐及探索
這篇文章主要介紹了基于vue-cli的webpack打包優(yōu)化實踐及探索,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
JavaScript 封裝Ajax傳遞的數(shù)據(jù)代碼
在使用Ajax傳輸數(shù)據(jù)時,少不了對傳遞的字符進行轉(zhuǎn)碼,我的實現(xiàn)方式是將需要傳遞的數(shù)據(jù)暫存到一js Bean中,將js Bean放到Array中,生成傳輸參數(shù)時對Array中的jsBean進行分解,得到相應(yīng)屬性信息并編碼..2009-06-06

