小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

ES6之函數(shù)擴展

 quasiceo 2018-09-30

目錄
一、 函數(shù)參數(shù)的默認(rèn)值
二、rest參數(shù)
三、嚴(yán)格模式
四、name 屬性
五、箭頭函數(shù)
六、雙冒號運算符(目前報錯,只是提案。)
七、重點: 尾調(diào)用優(yōu)化,尾遞歸優(yōu)化( Fibonacci 數(shù)列)
八、函數(shù)參數(shù)尾逗號

尾遞歸
總結(jié)一下,遞歸本質(zhì)上是一種循環(huán)操作。純粹的函數(shù)式編程語言沒有循環(huán)操作命令,所有的循環(huán)都用遞歸實現(xiàn),這就是為什么尾遞歸對這些語言極其重要。對于其他支持“尾調(diào)用優(yōu)化”的語言(比如 Lua,ES6),只需要知道循環(huán)可以用遞歸代替,而一旦使用遞歸,就最好使用尾遞歸。

下面是一個正常的遞歸函數(shù)。

function sum(x, y) {
  if (y > 0) {
    return sum(x + 1, y - 1);
  } else {
    return x;
  }
}

sum(1, 100000)
// Uncaught RangeError: Maximum call stack size exceeded(…)

上面代碼中,sum是一個遞歸函數(shù),參數(shù)x是需要累加的值,參數(shù)y控制遞歸次數(shù)。一旦指定sum遞歸 100000 次,就會報錯,提示超出調(diào)用棧的最大次數(shù)。

蹦床函數(shù)(trampoline)可以將遞歸執(zhí)行轉(zhuǎn)為循環(huán)執(zhí)行。

function trampoline(f) {
  while (f && f instanceof Function) {
    f = f();
  }
  return f;
}

上面就是蹦床函數(shù)的一個實現(xiàn),它接受一個函數(shù)f作為參數(shù)。只要f執(zhí)行后返回一個函數(shù),就繼續(xù)執(zhí)行。注意,這里是返回一個函數(shù),然后執(zhí)行該函數(shù),而不是函數(shù)里面調(diào)用函數(shù),這樣就避免了遞歸執(zhí)行,從而就消除了調(diào)用棧過大的問題。

然后,要做的就是將原來的遞歸函數(shù),改寫為每一步返回另一個函數(shù)。

function sum(x, y) {
  if (y > 0) {
    return sum.bind(null, x + 1, y - 1);
  } else {
    return x;
  }
}

上面代碼中,sum函數(shù)的每次執(zhí)行,都會返回自身的另一個版本。

現(xiàn)在,使用蹦床函數(shù)執(zhí)行sum,就不會發(fā)生調(diào)用棧溢出。

trampoline(sum(1, 100000))
// 100001

蹦床函數(shù)并不是真正的尾遞歸優(yōu)化,下面的實現(xiàn)才是。

function tco(f) {
  var value;
  var active = false;
  var accumulated = [];

  return function accumulator() {
    accumulated.push(arguments);
    if (!active) {
      active = true;
      while (accumulated.length) {
        value = f.apply(this, accumulated.shift());
      }
      active = false;
      return value;
    }
  };
}

var sum = tco(function(x, y) {
  if (y > 0) {
    return sum(x + 1, y - 1)
  }
  else {
    return x
  }
});

sum(1, 100000)
// 100001

上面代碼中,tco函數(shù)是尾遞歸優(yōu)化的實現(xiàn),它的奧妙就在于狀態(tài)變量active。默認(rèn)情況下,這個變量是不激活的。一旦進入尾遞歸優(yōu)化的過程,這個變量就激活了。然后,每一輪遞歸sum返回的都是undefined,所以就避免了遞歸執(zhí)行;而accumulated數(shù)組存放每一輪sum執(zhí)行的參數(shù),總是有值的,這就保證了accumulator函數(shù)內(nèi)部的while循環(huán)總是會執(zhí)行。這樣就很巧妙地將“遞歸”改成了“循環(huán)”,而后一輪的參數(shù)會取代前一輪的參數(shù),保證了調(diào)用棧只有一層。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多