`
JerryWang_SAP
  • 浏览: 1077276 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

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

阅读更多

程序员面试系列

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

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

 

如果要打印10个非波拉契数列的值,意味着我要重复调用9次fib函数,太麻烦。于是我写了个函数把fib调用包裹起来。

这个包裹函数有两个输入参数,n为希望生成非波拉契数列元素的个数,第二个参数sequence接受一个函数。

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

 

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

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

 

采用ES6的GeneratorFunction生成非波拉契数列

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

 

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

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

 

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

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

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

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

 

实际上,49行的变量lib只是维护了一个指向fib_generator的ITERATOR指针。

这个ITERATOR自带了一个名为next的方法,是ES6的原生实现,大家看上图调试器里的fib.next显示的是native code。Functiongenerator的神奇之处在于,当next方法被调用一次,则generator内部的函数体也只会执行一次。

单步执行,执行一次next方法:

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

 

注意调用栈,此时我们已经进入fib_generator函数体内部了:

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

 

一旦在FunctionGenerator实现体内部执行到yield关键字,则当前计算结果作为返回值返回给consumer。也就是说,一旦执行遇到yield,则自动从无限循环中退出。

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

 

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

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

 

采用ES6的FunctionGenerator打印出的结果和常规写法一致。

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

 

相信您面试的时候,如果能用ES6的FunctionGenerator完成这道题目,一定能让面试官对您刮目相看。

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

 

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

 

我写的程序员面试系列

Java面试系列-webapp文件夹和WebContent文件夹的区别?

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

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

使用JDK自带的工具jstack找出造成运行程序死锁的原因

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

JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

0
0
分享到:
评论

相关推荐

    JavaScript ES6新增特性

    JavaScript ES6新增特性

    三ES6新特性.pdf

    ES6,也就是ECMAScript 2015,是JavaScript语言的一个重要更新,它引入了许多新特性,使得JavaScript能够胜任更复杂的大型应用程序的开发,成为企业级开发语言。ES6新特性中比较突出的包括: 1. const关键字:使用...

    JavaScript ES6函数式编程入门经典_javascript_

    JavaScript ES6函数式编程是现代Web开发中的重要概念,它为开发者提供了更高效、更简洁的编程方式。本文将深入探讨ES6中的函数式编程特性,帮助初学者掌握这一核心技能。 1. **箭头函数**:箭头函数是ES6引入的一种...

    JavaScript:ES6新特性深入解析.docx

    JavaScript:ES6新特性深入解析.docx

    JavaScript ES6新特性解析-深入了解let与const关键字及块级作用域的应用与面试要点

    内容概要:本文档主要探讨了 JavaScript ES6 中引入的新关键字let和const及其所带来的改进特性。首先解释了let和const的作用与特性,如它们提供了块级作用域这一显著变化,并解决了传统var关键字存在的问题。同时...

    ES6新特性,看这就够了.pdf

    ES6(ECMAScript 2015)是JavaScript语言的一个重大更新版本,它带来了许多新特性,提高了开发效率和编程的便利性。在本篇文章中,我们将详细探讨几个ES6的关键新特性:let和const关键字、字符串的扩展、解构表达式...

    JavaScript:ES6新特性深入解析

    ### JavaScript:ES6新特性深入解析 #### 一、ES6的诞生背景 JavaScript 自1995年诞生以来,一直是互联网开发的重要组成部分。随着时间的推移和技术的发展,JavaScript 需要不断更新以适应日益复杂的开发需求。ES6...

    JavaScript ES6函数式编程入门经典_javascript_tall7cj_

    JavaScript ES6函数式编程入门经典是一本针对JavaScript开发者,尤其是初学者的教程,旨在帮助他们掌握ES6(ECMAScript 2015)的新特性,并深入理解函数式编程的概念和实践。函数式编程是一种编程范式,它强调将计算...

    JavaScript:ES6新特性:类与模块教程.docx

    JavaScript:ES6新特性:类与模块教程.docx

    JavaScript:ES6新特性:模板字符串与解构赋值.docx

    JavaScript:ES6新特性:模板字符串与解构赋值.docx

    JavaScript(ES6新增、W3C、MDN)最新参考手册.zip

    ES6,即ECMAScript 2015,是JavaScript语言的一个重要版本,引入了大量新特性和改进,极大地提升了开发效率和代码质量。W3C(万维网联盟)和MDN(Mozilla开发者网络)都是提供权威JavaScript技术文档和标准的重要...

    JavaScript:ES6新特性:类与模块教程

    ### JavaScript:ES6新特性:类与模块教程 #### 一、引言 随着Web技术的发展,JavaScript作为前端开发的核心语言之一,也在不断地进化和完善。ECMAScript 6(简称ES6),是JavaScript的一种规范版本,它带来了一...

    ES6 新特性示例代码.zip

    ES6,全称ECMAScript 2015,是JavaScript语言的一个重要更新版本,引入了许多新特性,显著提升了开发效率和代码质量。这个压缩包"ES6 新特性示例代码.zip"包含了与ES6新特性相关的代码示例,帮助我们更直观地理解...

    JavaScript:ES6新特性:模板字符串与解构赋值

    ### JavaScript:ES6新特性详解:模板字符串与解构赋值 #### 1. ES6简介与环境设置 ##### 1.1 ES6新特性概述 ES6,即ECMAScript 2015,是JavaScript语言的一个重要版本,自2015年发布以来,对JavaScript的发展...

    ES6新特性.docx

    ES6版本的更新,不仅丰富了JavaScript的特性,还使其现代化功能更加强大,并且更易于学习和使用。 ES6的发展背景源于之前JavaScript语言更新主要集中在ECMAScript 5(ES5)上,但随着Web应用复杂度的提高,ES5已...

    JavaScript ES6函数式编程入门经典

    《JavaScriptES6函数式编程入门经典》使用JavaScriptES6带你学习函数式编程。你将学习柯里化、偏函数、高阶函数以及Monad等概念。  目前,编程语言已经将... ●了解ES6的函数式编程特性,例如扩展运算符和Generator

    前端开发之ES6新特性

    前端开发之ES6新特性

    ChromeTools:在最新的Google Chrome浏览器中可以使用JavaScript ES6工具。 该存储库可以包含适用于Chrome中任何上下文的工具

    ChromeTools正是一个专为最新版Google Chrome浏览器设计的工具集合,充分利用了JavaScript ES6的新特性,旨在帮助开发者更高效地处理浏览器环境下的各种任务,无论是在浏览器、辅助程序、扩展程序还是应用程序中。...

    es6新特性 学习word版2018最新

    新特性 let、const let 定义的变量不会被变量提升,const 定义的常量不能被修改,let 和 const 都是块级作用域 ES6前,js 是没有块级作用域 {} 的概念的。(有函数作用域、全局作用域、eval作用域) ES6后,...

    ES6新特性思维导图

    查看我整理的ES新特性思维导图,参照思维导图可以宏观角度来学习ES6的新特性。配合Day05-Day07进行学习效果更佳

Global site tag (gtag.js) - Google Analytics