使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)

简介: 使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)

面试题:用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为2
console.log(generator.current);
// 一旦执行next函数,则执行其指向的return fib(b, _current); 1 + 2 = 3
var result = generator.next();
console.log(result.current); // 打印3

image.png

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;
}

image.png

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)的无限循环内的,所以这段代码是如何工作的呢?

image.png

最好的学习办法就是单步调试。


代码第40行到第47行,我们使用了ES6 function*关键字得到了一个"function generator"。在这个generator内部,我们定义了一个无限循环,用于计算非波拉契数列。


第49行,我们用()调用了这个generator,将结果存储在变量fib里。直到此时,function generator的实现体,即代码41~45行还没有得到执行。

image.png

image.png

下列简单的循环会打印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内部是一个无限循环。

image.png

image.png


相关文章
|
28天前
|
JavaScript
js计算时间差,包括计算,天,时,分,秒
js计算时间差,包括计算,天,时,分,秒
126 16
|
28天前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
2天前
|
前端开发 JavaScript 小程序
JavaScript的ES6中Promise的使用以及个人理解
JavaScript的ES6中Promise的使用以及个人理解
9 1
|
2天前
|
缓存 JavaScript 前端开发
探索Vue.js中的计算属性与侦听器
【10月更文挑战第5天】探索Vue.js中的计算属性与侦听器
10 1
|
18天前
|
JavaScript 前端开发 Oracle
软件工程师,学习下JavaScript ES6新特性吧
软件工程师,学习下JavaScript ES6新特性吧
37 9
|
23天前
|
前端开发 JavaScript
ES6新标准下JS异步编程Promise解读
ES6新标准下JS异步编程Promise解读
28 3
|
23天前
|
JavaScript 安全
ES6中JS类实现的解读
ES6中JS类实现的解读
18 2
|
2天前
|
缓存 JavaScript 前端开发
深入理解Vue.js中的计算属性与侦听属性
【10月更文挑战第5天】深入理解Vue.js中的计算属性与侦听属性
8 0
|
2天前
|
缓存 JavaScript 前端开发
探索Vue.js中的计算属性与侦听器:深入理解与实践
【10月更文挑战第5天】探索Vue.js中的计算属性与侦听器:深入理解与实践
9 0
|
JavaScript 前端开发
利用Javascript实现简单计算
利用Javascript实现简单计算
利用Javascript实现简单计算