摘要:遞歸一個(gè)函數(shù)可以指向并調(diào)用自身。這是的一個(gè)獨(dú)特的用法,在這個(gè)結(jié)構(gòu)下無法替代,出錯(cuò)但我們可以用下面這種方式,把遞歸函數(shù)賦值給一個(gè)變量
遞歸(Recursion)
一個(gè)函數(shù)可以指向并調(diào)用自身(call itself)。有三種方法可以達(dá)到這個(gè)目的:
函數(shù)名
arguments.callee
作用域下的一個(gè)指向該函數(shù)的變量名
上述概念引用自MDN,對(duì)遞歸概念不清楚的可以自行查看;
遞歸函數(shù)的執(zhí)行在這里我們討論一下遞歸函數(shù)中遞歸后的語句如何執(zhí)行,先看這樣一個(gè)例子:
function rec(x){ if(x!==1){ console.log(x) rec(x-1) console.log(x) } } rec(5) //輸出為5 4 3 2 2 3 4 5
以上這段代碼執(zhí)行的結(jié)果就是遞歸前的語句順序執(zhí)行,遞歸后的語句倒序執(zhí)行。初看到這段代碼,完全不能理解它執(zhí)行的順序。通過調(diào)試讓代碼逐行執(zhí)行,可以看到執(zhí)行的順序,其實(shí)就是一層一層執(zhí)行遞歸,每執(zhí)行到rec(x-1)時(shí)就重新執(zhí)行該函數(shù),遞歸后的語句會(huì)在遞歸執(zhí)行到最里層后再由內(nèi)向外輸出。
CSDN上的一篇博客很好的總結(jié)了遞歸的特性如下:
1 每一次函數(shù)調(diào)用都會(huì)有一次返回.當(dāng)程序流執(zhí)行到某一級(jí)遞歸的結(jié)尾處時(shí),它會(huì)轉(zhuǎn)移到前一級(jí)遞歸緊接著的后面繼續(xù)執(zhí)行.
2 遞歸函數(shù)中,位于遞歸調(diào)用前的語句和各級(jí)被調(diào)函數(shù)具有相同的順序.如打印語句 #1 位于遞歸調(diào)用語句前,它按照遞歸調(diào)用的順序被執(zhí)行了 4 次.
3 每一級(jí)的函數(shù)調(diào)用都有自己的私有變量.
4 遞歸函數(shù)中,位于遞歸調(diào)用語句后的語句的執(zhí)行順序和各個(gè)被調(diào)用函數(shù)的順序相反.
5 雖然每一級(jí)遞歸有自己的變量,但是函數(shù)代碼并不會(huì)得到復(fù)制.
6 遞歸函數(shù)中必須包含可以終止遞歸調(diào)用的語句.
在這個(gè)例子中,終止遞歸調(diào)用的條件是if(x!==1),如果調(diào)用時(shí)取值x小于1,會(huì)構(gòu)成死循環(huán);這個(gè)例子中的遞歸采用了通過函數(shù)名調(diào)用的方法。
下面我們?cè)儆懻撘幌耡rgumengts.callee方式,在ES5嚴(yán)格模式下,callee是無法使用的,原因詳見MDN中arguments.callee。
這是callee的一個(gè)獨(dú)特的用法,在這個(gè)結(jié)構(gòu)下無法替代,
function factorial(num){ if (num <= 1){ return 1; } else { return num * factorial(num-1); } } var anotherFactorial = factorial; alert(anotherFactorial(4)); //出錯(cuò)!
但我們可以用下面這種方式,把遞歸函數(shù)賦值給一個(gè)變量:
var factorial = (function f(num){ if (num <= 1){ return 1; } else { return num * f(num-1); } });
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/86925.html
摘要:每個(gè)函數(shù)調(diào)用都將開辟出一小塊稱為堆棧幀的內(nèi)存。當(dāng)?shù)诙€(gè)函數(shù)開始執(zhí)行,堆棧幀增加到個(gè)。當(dāng)這個(gè)函數(shù)調(diào)用結(jié)束后,它的幀會(huì)從堆棧中退出。保持堆棧幀跟蹤函數(shù)調(diào)用的狀態(tài),并將其分派給下一個(gè)遞歸調(diào)用迭。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個(gè)流淌著滬江血液的純粹工程:認(rèn)真,是 HTM...
摘要:專題系列第十八篇,講解遞歸和尾遞歸定義程序調(diào)用自身的編程技巧稱為遞歸。然而非尾調(diào)用函數(shù),就會(huì)創(chuàng)建多個(gè)執(zhí)行上下文壓入執(zhí)行上下文棧。所以我們只用把階乘函數(shù)改造成一個(gè)尾遞歸形式,就可以避免創(chuàng)建那么多的執(zhí)行上下文。 JavaScript 專題系列第十八篇,講解遞歸和尾遞歸 定義 程序調(diào)用自身的編程技巧稱為遞歸(recursion)。 階乘 以階乘為例: function factorial(n...
摘要:下面進(jìn)行簡單的作圖分析注意到,遞歸函數(shù)從外層,沿著計(jì)算的路徑,經(jīng)過三次遞歸調(diào)用函數(shù),到達(dá)基準(zhǔn),在基準(zhǔn)層分別計(jì)算遞歸函數(shù)內(nèi)部的三部分左側(cè)最大子序列與右側(cè)最大子序列的和,并利用求出最大者返回。 問題描述 問題:給定整數(shù)序列,求解其中最大子序列(連續(xù)的序列)。 思路分析 利用分治和遞歸的思想求解,在《數(shù)據(jù)結(jié)構(gòu)與算法分析(Java語言描述)》Page29,作者給出了具體的java代碼。...
摘要:鏈表與遞歸已經(jīng)從底層完整實(shí)現(xiàn)了一個(gè)單鏈表這樣的數(shù)據(jù)結(jié)構(gòu),并且也依托鏈表這樣的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)了棧和隊(duì)列,在實(shí)現(xiàn)隊(duì)列的時(shí)候?qū)︽湵磉M(jìn)行了一些改進(jìn)。計(jì)算這個(gè)區(qū)間內(nèi)的所有數(shù)字之和。 showImg(https://segmentfault.com/img/remote/1460000018597053?w=1832&h=9943); 前言 【從蛋殼到滿天飛】JAVA 數(shù)據(jù)結(jié)構(gòu)解析和算法實(shí)現(xiàn),全部文...
摘要:鏈表與遞歸已經(jīng)從底層完整實(shí)現(xiàn)了一個(gè)單鏈表這樣的數(shù)據(jù)結(jié)構(gòu),并且也依托鏈表這樣的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)了棧和隊(duì)列,在實(shí)現(xiàn)隊(duì)列的時(shí)候?qū)︽湵磉M(jìn)行了一些改進(jìn)。計(jì)算這個(gè)區(qū)間內(nèi)的所有數(shù)字之和。 showImg(https://segmentfault.com/img/remote/1460000018597053?w=1832&h=9943); 前言 【從蛋殼到滿天飛】JAVA 數(shù)據(jù)結(jié)構(gòu)解析和算法實(shí)現(xiàn),全部文...
閱讀 1774·2021-11-12 10:36
閱讀 1676·2021-11-12 10:36
閱讀 3511·2021-11-02 14:46
閱讀 3908·2019-08-30 15:56
閱讀 3729·2019-08-30 15:55
閱讀 1528·2019-08-30 15:44
閱讀 1112·2019-08-30 14:00
閱讀 2782·2019-08-29 18:41