摘要:中尾遞歸優(yōu)化支持尾遞歸優(yōu)化如果一個(gè)函數(shù)的最后一個(gè)操作是函數(shù)調(diào)用,那么將會(huì)用跳轉(zhuǎn)而不是子調(diào)用。自從年雙十一正式上線,累計(jì)處理了億錯(cuò)誤事件,付費(fèi)客戶有陽(yáng)光保險(xiǎn)核桃編程荔枝掌門(mén)對(duì)微脈青團(tuán)社等眾多知名企業(yè)。
譯者按: 有時(shí)候會(huì)遇到Maximum call stack size exceeded的問(wèn)題,本文教你stack size的計(jì)算方法。
原文: The maximum call stack size
譯者: Fundebug
為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。
如果你寫(xiě)了一個(gè)一直調(diào)用自身的死循環(huán),那么恭喜你,很快就可以看到報(bào)錯(cuò):Uncaught RangeError: Maximum call stack size exceeded。那么這個(gè)call stack size有多少呢?
1. 計(jì)算方法如下的方法可以為你計(jì)算出你使用的JavaScript引擎可以支持多深的調(diào)用(由Ben Alman的一段代碼獲得靈感):
function computeMaxCallStackSize() { try { return 1 + computeMaxCallStackSize(); } catch (e) { // Call stack overflow return 1; } }
運(yùn)行得到如下三個(gè)結(jié)果:
Node.js: 11034
Firefox: 50994
Chrome: 10402
這些數(shù)字代表了什么呢?Mr.Aleph告訴我在V8,可調(diào)用的層數(shù)基于兩個(gè)方面:1. 棧的大小;2. 每一棧幀的大小(用于記錄函數(shù)參數(shù)和局部變量)。你可以在computeMaxCallStackSize聲明局部變量來(lái)測(cè)試,你會(huì)發(fā)現(xiàn)數(shù)字變小。
2. ECMAScript 6中尾遞歸優(yōu)化ECMAScript 6支持尾遞歸優(yōu)化:如果一個(gè)函數(shù)的最后一個(gè)操作是函數(shù)調(diào)用,那么將會(huì)用“跳轉(zhuǎn)”而不是“子調(diào)用”。也就是說(shuō)如果你將computeMaxCallStackSize重寫(xiě)成如下形式,在ES6的嚴(yán)格模式下,就會(huì)一直運(yùn)行了。
function computeMaxCallStackSize(size) { size = size || 1; return computeMaxCallStackSize(size + 1); }
備注:justjavac提到由于尾遞歸優(yōu)化會(huì)導(dǎo)致堆棧報(bào)錯(cuò)信息不準(zhǔn)確而逐漸不被支持,請(qǐng)大家移步評(píng)論區(qū)了解詳情。
3. 亮點(diǎn)評(píng)論Andrei: “ECMAScript 6”版本的代碼根本跑不通。雖然size會(huì)被更改,但是最終并沒(méi)有值返回。
回復(fù)Andrei: 有趣!你不能用這段代碼去計(jì)算stack size。在ES6下,這段代碼會(huì)一直運(yùn)行,因此不會(huì)返回?cái)?shù)據(jù)。在其它情況下,會(huì)返回RangeError。為了使其工作,我把代碼重寫(xiě)了一下:
var computeMaxCallStackSize = (function() { return function() { var size = 0; function cs() { try { size++; return cs(); } catch(e) { return size + 1; } } return cs(); }; }());關(guān)于Fundebug
Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了10億+錯(cuò)誤事件,付費(fèi)客戶有陽(yáng)光保險(xiǎn)、核桃編程、荔枝FM、掌門(mén)1對(duì)1、微脈、青團(tuán)社等眾多知名企業(yè)。歡迎大家免費(fèi)試用!
版權(quán)聲明轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/06/15/call-stack-size/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95755.html
摘要:一鍵生成屬于自己的歷史報(bào)告,看看你對(duì)自己的了解程度有多深簡(jiǎn)介近幾年,由于微信的流行,大部分人不再頻繁使用,所以我們對(duì)于自己的數(shù)據(jù)并不是特別了解。這里要說(shuō)明的是,加密函數(shù)的獲取,需要具備一定的抓包基礎(chǔ)才能獲取得到。 [TOC] 一鍵生成屬于自己的QQ歷史報(bào)告,看看你對(duì)自己的QQ了解程度有多深? 簡(jiǎn)介 近幾年,由于微信的流行,大部分人不再頻繁使用QQ,所以我們對(duì)于自己的QQ數(shù)據(jù)并不是特別了...
摘要:之前的閉包也好,自執(zhí)行函數(shù)也好,都是模塊化的一些嘗試,直到規(guī)范推出之后,模塊化才真正迅猛發(fā)展起來(lái)。因?yàn)橛辛四K化的概念,才有了按需加載的概念。 前言 我們來(lái)玩樂(lè)高積木吧 模塊化Js已經(jīng)成為了老生常談,不過(guò)在JavaScript設(shè)計(jì)之初,由于定位的問(wèn)題并沒(méi)有提供類的功能,開(kāi)發(fā)者需要模擬出類似的功能,來(lái)隔離、組織復(fù)雜的JavaScript代碼。之前的閉包也好,自執(zhí)行函數(shù)也好,都是模塊化的一...
摘要:之前的閉包也好,自執(zhí)行函數(shù)也好,都是模塊化的一些嘗試,直到規(guī)范推出之后,模塊化才真正迅猛發(fā)展起來(lái)。因?yàn)橛辛四K化的概念,才有了按需加載的概念。 前言 我們來(lái)玩樂(lè)高積木吧 模塊化Js已經(jīng)成為了老生常談,不過(guò)在JavaScript設(shè)計(jì)之初,由于定位的問(wèn)題并沒(méi)有提供類的功能,開(kāi)發(fā)者需要模擬出類似的功能,來(lái)隔離、組織復(fù)雜的JavaScript代碼。之前的閉包也好,自執(zhí)行函數(shù)也好,都是模塊化的一...
摘要:父組件聲明自己支持父組件提供一個(gè)函數(shù),用來(lái)返回相應(yīng)的對(duì)象子組件聲明自己需要使用我胡漢三又回來(lái)了點(diǎn)擊我如果是父組件向子組件單向通信,可以使用變量,如果子組件想向父組件通信,同樣可以由父組件提供一個(gè)回調(diào)函數(shù),供子組件調(diào)用,回傳參數(shù)。 在使用 React 的過(guò)程中,不可避免的需要組件間進(jìn)行消息傳遞(通信),組件間通信大體有下面幾種情況: 父組件向子組件通信 子組件向父組件通信 跨級(jí)組件之間...
showImg(https://segmentfault.com/img/bVbsRlD?w=211&h=184); 今天是520。一句溫柔的問(wèn)候,一束美麗的鮮花,一段真情的告白。但是作為一名與眾不同的程序員,我們可不僅僅擁有上面的傳情方法,別忘了每個(gè)人的手上可是都有其他人不具備的神奇技能,就是我們每天辛辛苦苦敲下的代碼。 在這個(gè)特殊的日子,就用我們手中的魔法代碼,來(lái)給你的她(他)制作出一個(gè)與眾不...
閱讀 1306·2021-11-16 11:44
閱讀 3774·2021-10-09 10:01
閱讀 1767·2021-09-24 10:31
閱讀 3855·2021-09-04 16:41
閱讀 2527·2021-08-09 13:45
閱讀 1225·2019-08-30 14:08
閱讀 1790·2019-08-29 18:32
閱讀 1651·2019-08-26 12:12