使用JavaScript ES6的新特性計算Fibonacci(非波拉契數列)
程式設計師面試系列
Java面試系列-webapp資料夾和WebContent資料夾的區別?
程式設計師面試系列:Spring MVC能響應HTTP請求的原因?
Java程式設計師面試系列-什麼是Java Marker Interface(標記介面)
JavaScript面試系列:JavaScript設計模式之橋接模式和懶載入
面試題:用JavaScript開發一個函式,列印非波拉契數列。
我們只要記住非波拉契數列的計算公式,就不難寫出來了:
F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)
我寫的JavaScript程式碼如下:
var fib = function (a, b) { var _current = a + b; return { current: _current, next: function () { return fib(b, _current); } } }
把當前這一輪的計算結果儲存到第二行的變數_current裡,並透過屬性current返回給呼叫者。返回的json物件除了current屬性外,還有另一個屬性next,指向一個閉包函式呼叫。一旦next指向的函式再次被呼叫,則會再次觸發數列的計算。
var generator = fib(1,1);// 前一行呼叫fib(1,1)計算1+1的結果為2,將2儲存到_current裡透過current屬性返回,所以列印2// 同時返回next函式,函式體為return fib(b, _current); 此時b為1,_current為2console.log(generator.current);// 一旦執行next函式,則執行其指向的return fib(b, _current); 1 + 2 = 3var result = generator.next();console.log(result.current); // 列印3
如果要列印10個非波拉契數列的值,意味著我要重複呼叫9次fib函式,太麻煩。於是我寫了個函式把fib呼叫包裹起來。
這個包裹函式有兩個輸入引數,n為希望生成非波拉契數列元素的個數,第二個引數sequence接受一個函式。
var take = function(n, sequence) { var result = []; var temp = sequence; for (var i = 0; i < n; i++) { result.push(temp.current); temp = temp.next(); } return result; }
現在我只需要一行語句,就能列印10個非波拉契數列的元素出來。
console.log(take(10, fib(1,1)));
採用ES6的GeneratorFunction生成非波拉契數列
ES6提供了原生GeneratorFunction的支援,語法非常有特色,關鍵字function後面緊跟一個星號。GeneratorFunction的詳細介紹參考官網: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
先看如何用GeneratorFunction這個黑科技重新實現非波拉契樹立的生成。程式碼如下:
var fib_generator = function *(){ var current = 0, next = 1; while(true) { [next, current] = [next+current, next]; yield current; } }var fib = fib_generator();for(var i = 0; i < 10; i++){ console.log(fib.next().value); }
第5行從語義上非常清晰地體現出了非波拉契數列的計算公式:
F(n)=F(n-1)+F(n-2)
然而它是包含在一個while(true)的無限迴圈內的,所以這段程式碼是如何工作的呢?
最好的學習辦法就是單步除錯。
程式碼第40行到第47行,我們使用了ES6 function*關鍵字得到了一個"function generator"。在這個generator內部,我們定義了一個無限迴圈,用於計算非波拉契數列。
第49行,我們用()呼叫了這個generator,將結果儲存在變數fib裡。直到此時,function generator的實現體,即程式碼41~45行還沒有得到執行。
實際上,49行的變數lib只是維護了一個指向fib_generator的ITERATOR指標。
這個ITERATOR自帶了一個名為next的方法,是ES6的原生實現,大家看上圖偵錯程式裡的fib.next顯示的是native code。Functiongenerator的神奇之處在於,當next方法被呼叫一次,則generator內部的函式體也只會執行一次。
單步執行,執行一次next方法:
注意呼叫棧,此時我們已經進入fib_generator函式體內部了:
一旦在FunctionGenerator實現體內部執行到yield關鍵字,則當前計算結果作為返回值返回給consumer。也就是說,一旦執行遇到yield,則自動從無限迴圈中退出。
下列簡單的迴圈會列印10個非波拉契數列的元素:
for(var i = 0; i < 10; i++){ var currentResult = fib.next(); console.log(currentResult.value); }
從上面的程式碼能看出,yield關鍵字返回一個json物件給消費者,該物件有個名為name的屬性,包含的是具體計算的數值。Json物件的另一個屬性名為done,型別為boolean,意思是這個FunctionGenerator的函式體執行是否已經結束。在我的這個例子裡,每次next呼叫的yield返回的Json物件的done屬性都為false,因為我的FunctionGenerator內部是一個無限迴圈。
採用ES6的FunctionGenerator列印出的結果和常規寫法一致。
相信您面試的時候,如果能用ES6的FunctionGenerator完成這道題目,一定能讓面試官對您刮目相看。
我寫的程式設計師面試系列
Java面試系列-webapp資料夾和WebContent資料夾的區別?
程式設計師面試系列:Spring MVC能響應HTTP請求的原因?
Java程式設計師面試系列-什麼是Java Marker Interface(標記介面)
JavaScript面試系列:JavaScript設計模式之橋接模式和懶載入
要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2213408/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用JavaScriptES6的新特性計算Fibonacci(非波拉契數列)JavaScript
- 如何在ABAP裡用函數語言程式設計思想列印出非波拉契Fibonacci(數列)函數程式設計
- JS尾遞迴優化斐波拉契數列JS遞迴優化
- 斐波那契數列(Fibonacci)遞迴和非遞迴實現遞迴
- python中用遞迴的方法實現斐波拉契數列Python遞迴
- 用閉包替換遞迴實現斐波拉契數列遞迴
- JavaScript斐波納契數列非遞迴演算法JavaScript遞迴演算法
- fibonacci斐波那契數列詳解 遞迴求Fn非遞迴求Fn求n最近的斐波那契數遞迴
- 斐波那契數列的分治法計算
- 前端-JavaScript新特性(ES6)前端JavaScript
- 計算斐波那契數列的演算法演算法
- python 學習-使用生成器輸出楊輝三角和斐波拉契數列Python
- 【演算法詳解】斐波那契數列 - Fibonacci sequence演算法
- JavaScript回顧00:字串,陣列,物件和ES6新特性JavaScript字串陣列物件
- rust實戰系列 - 使用Iterator 迭代器實現斐波那契數列(Fibonacci )Rust
- ES6新特性:JavaScript中的Reflect物件JavaScript物件
- 【演算法】Fibonacci(斐波那契數列)相關問題演算法
- javascript ES6 新特性之 解構JavaScript
- 裴波那契數列(javascript實現)JavaScript
- js計算斐波那契數列程式碼例項JS
- HDU2813Interesting Fibonacci(斐波那契數列+迴圈節)REST
- ES6新特性:JavaScript中的Map和WeakMap物件JavaScript物件
- JavaScript ES6 特性JavaScript
- 斐波那契數列的遞迴和非遞迴實現遞迴
- JavaScript 實現:輸出斐波那契數列JavaScript
- ES6新特性
- ES6常用的新特性
- ES6新特性:JavaScript中內建的延遲物件PromiseJavaScript物件Promise
- [譯] 斐波那契數列中的偶數 (Python vs. JavaScript)PythonJavaScript
- ES6:下一版本的JavaScript的新特性JavaScript
- “天池PAI-DSW”建立一個斐波那契數列計算函式AI函式
- es6新特性分享
- 斐波那契數列
- 每日一算 -- 斐波那契數列型別題型別
- 使用ES6新特性開發微信小程式微信小程式
- HITOJ 1864 求Fibonacci數列的位數
- 使用Python實現斐波那契數列Python
- ES6新特性總結