斐波那契数列与arguments.callee

HTML5学堂:提到斐波那契数列,很多人还不是太清楚,但是如果提到兔子繁殖这个经典题目,相信学过计算机语言的人们会立刻感觉“亲切”起来,今天我们就来说说斐波那契数列,也讲一讲里面用到的arguments.callee。

斐波那契数列

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

特别指出:第0项是0,第1项是第一个1。

这个数列从第2项开始,每一项都等于前两项之和。

兔子繁殖问题

斐波那契数列又因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。

题目为:兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?

我们不妨拿新出生的一对小兔子分析一下:

两个月后,生下一对小兔对数共有两对

三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对

……………………

关于斐波那契数列的JS代码实现

基本思路:判断当前是第几次,如果是第一次(下标为0)或第二次(下标为1)则直接给予赋值,如果是大于两次,则是之前两项的和。

var result = [];
function fn(n) { // 典型的斐波那契数列 - 版权归属:HTML5学堂
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        if (result[n]) {
            return result[n];
        } else {
            result[n] = fn(n - 1) + fn(n - 2);
            return result[n];
        }
    }
}

那么到此为止是不是结束了呢?对于这段代码当中的fn调用,其实可以换为arguments.callee,这个也是利利今天要讲解的内容之一。

arguments.callee

Tips:对于此知识的讲解,需要先了解arguments的相关知识,如果你使用的是官网查看,可以查看——>arguments知识讲解查看arguments的详细讲解。如果你是通过我们的微信号查看的,可以通过发送arguments,查看关于arguments的基础知识。

callee属性的初始值就是正被执行的 Function 对象,表示对函数对象本身的引用。有利于匿名函数的递归或者保证函数的封装性。

该属性仅当相关函数正在执行时才可用。

callee拥有length属性,arguments.length是实参长度,arguments.callee.length是形参长度,由此可以判断调用时形参长度是否和实参长度一致。

arguments.callee并不是很推荐使用

callee最广泛的用途就是在匿名函数里递归调用自身,但 ECMAScript 3 已允许有名字的函数表达式,且不会污染命名空间,所以在实现同样的功能时并不会变得不优雅。

arguments 是个很大的对象,每次递归调用时都需要重新创建(虽然 arguments.callee 是不变的,但是 arguments.caller 是不一样的,调用的参数也不一样的)。ECMAScript5的标准中Strict Mode禁止使用。

如上的代码也可以书写成这样:

var result = [];
function fn(n) { // 典型的斐波那契数列 - 版权归属:HTML5学堂
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        if (result[n]) {
            return result[n];
        } else {
            result[n] = arguments.callee(n - 1) + arguments.callee(n - 2);
            return result[n];
        }
    }
}

functionName.caller

扩展讲解一下caller这个东西吧

functionName 对象是所执行函数的名称。

如果函数是由顶层调用的,那么 caller包含的就是 null 。如果在字符串上下文中使用 caller属性,那么结果和 functionName.toString 一样,也就是说,显示的是函数的反编译文本。

function h5course(num1) {
    console.log(h5course.caller); // null
}
h5course(2, 3);
h5course.toString(); // 返回字符串,内容为这个函数

生活当中的斐波那契数列

最后,作为科学普及,我们扯扯生活中的“斐波那契数列”。

黄金分割

随着数列项数的增加,前一项与后一项之比越来越逼近黄金分割的数值0.6180339887

自然界花朵的花瓣

松果、凤梨、树叶的排列、某些花朵的花瓣数(典型的有向日葵花瓣),蜂巢,蜻蜓翅膀。

譬如:百合花花瓣数目为3,梅花5瓣,飞燕草8瓣,万寿菊13瓣,向日葵21或34瓣,雏菊有34,55和89三个数目的花瓣。

HTML5小编-利利 耗时2.5h

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-04-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小樱的经验随笔

POJ 2492 A Bug's Life

A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions:...

27810
来自专栏码匠的流水账

聊聊storm TridentTopology的构建

storm-core-1.2.2-sources.jar!/org/apache/storm/trident/TridentTopology.java

792
来自专栏五分钟学算法

LeeCode题目图解

There is an English version of README here. just click it!

1092
来自专栏程序你好

如何使用Java Stream Collectors(归约器)?

Java 8引入了Stream API,它允许我们以声明的方式处理数据。此外,Stream还可以在不需要编写多线程代码的情况下使用多核架构。

631
来自专栏SeanCheney的专栏

《Pandas Cookbook》第09章 合并Pandas对象

891
来自专栏函数式编程语言及工具

SDP(9):MongoDB-Scala - data access and modeling

    MongoDB是一种文件型数据库,对数据格式没有硬性要求,所以可以实现灵活多变的数据存储和读取。MongoDB又是一种分布式数据库,与传统关系数据库不同...

3644
来自专栏進无尽的文章

编码篇-开发中关于数字的那些事儿

在日常的开发中我们随时都会跟数字打着交道,对数字的处理也是很平常的事,本文仅对常用的数字操作一个小结,当一个笔记方便日后查看,也希望读者能从中收获些感觉有用的知...

831
来自专栏数据结构与算法

P2580 于是他错误的点名开始了

题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人。 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉...

2797
来自专栏calmound

UVA 10604 Chemical Reaction(六维dp数组)

题意:有六种不同的试剂,放于试管中,不同的试剂融合其产生的热量不同,且生成的新试剂也不相同,问最后最低温度是多少。 分析:由于只有六种试剂,所以开辟一个六维dp...

3337
来自专栏码匠的流水账

Java10的新特性

上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见What’s New in JDK 10 - New Features and Enhanc...

410

扫码关注云+社区