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

汪子熙SAP / 2018年08月29日 21:26

新闻

程序员面试系列

Java面试系列-webapp文件夹和WebContent文件夹的差异?

程序员面试系列:Spring MVC能呼应HTTP恳求的原因?

Java程序员面试系列-什么是Java Marker Interface(符号接口)

运用JDK自带的东西jstack找出形成运转程序死锁的原因

编程面试题:编写一个会形成数据库死锁的运用

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为2

console.log(generator.current);

// 一旦履行next函数,则履行其指向的return fib(b, _current); 1 + 2 = 3

var 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(符号接口)

运用JDK自带的东西jstack找出形成运转程序死锁的原因

编程面试题:编写一个会形成数据库死锁的运用

JavaScript面试系列:JavaScript规划形式之桥接形式和懒加载

1.黑方糖-您的科技人生遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.黑方糖-您的科技人生的原创文章,请转载时务必注明文章作者和"来源:黑方糖-您的科技人生",不尊重原创的行为黑方糖-您的科技人生或将追究责任;3.作者投稿可能会经黑方糖-您的科技人生编辑修改或补充。