递归函数大家都应该比较熟吧?那么,如何在javascript中书写一个完美的递归函数呢?且听我娓娓道来。

递归函数

写的时候,查了一下维基百科对递归函数的定义,恕我愚钝,简直太深奥了!所以,我还是简单的说说我对递归函数的理解吧。递归函数,说白了就是在函数内部引用函数自身,最终到给定的递归结束条件时回溯。当然,你也可以不给定结束条件,死了别挂我(╯﹏╰)

使用javascript书写递归函数

现在,一步一步,摩擦摩擦,在皎洁的编辑器上,来开始使用javascript写递归函数吧!

  1. function fun(num){
  2. if(num <= 1){
  3. return 1;
  4. } else{
  5. return num * fun(--num);
  6. }
  7. }

好了,不错,一个堪称经典的递归求阶乘的函数诞生了。事情肯定不会这么顺利,一定是个圈套。我们来如下调用以下看看会怎么样?

  1. var test = fun;
  2. fun = null;
  3. console.log(test(7));

呵呵,居然报错了

  1. Uncaught TypeError: object is not a function

嗯,报了类型错误。。。

回过头去看看我们是如何调用的。发现问题了吧!我们把fun赋给了test,然后把fun给回收掉了。为什么会出错呢?因为像function这种赋值其实是引用传递,只是把指向函数的指针(这里说地址也行)赋给test了。但我们把fun赋值为null的时候,函数都已经被回收了,拿什么来执行?知道问题所在了,我决定换种方式来定义:

  1. function fun(num){
  2. if(num <= 1){
  3. return 1;
  4. } else{
  5. return num * arguments.callee(--num);
  6. }
  7. }

然后测试一下:

  1. var test = fun;
  2. fun = null;
  3. console.log(test(7));

OK,测试通过!

但是在某一天,当我实际码代码的时候,问题又出现了。什么问题呢?我们来看一下:

  1. Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

╮(╯▽╰)╭哎!可怜啊!因为我使用了"use strict"!严格模式下是不允许的。。。

好吧!继续想办法!既然不能使用arguments.callee(),那还是想想其他的方式吧。

看下面的代码:

  1. var fun = (function f(num){
  2. if(num <= 1){
  3. return 1;
  4. } else{
  5. return num * f(--num);
  6. }
  7. });

然后我测试了以下,神奇的通过了,暂时没有发现任何问题!

为什么呢?因为我们使用了“()”,巧妙地使用命名函数表达式来达到了同样的效果。

参考资料

  1. 《JavaScript高级程序设计(第三版)》
  2. 《JavaScript启示录》

如何使用javascript书写递归函数的更多相关文章

  1. JSPatch 可以让你用 JavaScript 书写原生 iOS APP

    简介   JSPatch 可以让你用 JavaScript 书写原生 iOS APP.只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本 ...

  2. JavaScript 书写位置

    类似于 CSS 样式,JavaScript 也有三种不同位置的书写方式. 1.写在行内 <input type="button" value="按钮" o ...

  3. JavaScript中递归函数用法需要注意的

    <script> function sum(num){ if(num<=1){ return 1; }else{ return num*sum(num-1);//return num ...

  4. 规范javascript书写

    空白 缩进 换行限制 if while for do 2.  命名 常量 URL_CONFIG 变量 listLen 函数命名 调用函数  function setStyle(dom, name, v ...

  5. javaScript书写规范

    命名规范. 常量名    全部大写并单词间用下划线分隔    如:CSS_BTN_CLOSE.TXT_LOADING对象的属性或方法名    小驼峰式(little camel-case)    如: ...

  6. Javascript书写位置

    1.行内式js(很少使用) 以on开头,如onclick HTML中推荐双引号,JS推荐单引号 2.内嵌式js(常用) <script> alert('hello world'); < ...

  7. [译]Javascript中的递归函数

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  8. JavaScript的书写格式及书写的注意点

    JavaScript书写格式: 1.行内样式: 写在标签内部 2.内嵌样式(内联样式) : 写在一对head标签中 3.外链样式: 写在一个单独的.js文件中, 再导入进来 JavaScript书写格 ...

  9. 常用html、CSS、javascript前端命名规范

    无论是从技术角度还是开发视角,对于web前端开发规范文档都有一定规范,本文就css3和html5的发展前景总结了一系列的web开发文档,仅供大家参考. 规范目的: 为提高团队协作效率, 便于后台人员添 ...

随机推荐

  1. Linux 的进程组、会话、守护进程

    一.进程组ID 每个进程都属于一个进程组.每个进程组有一个领头进程.进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号.每个进程组都有唯一的进程组ID(整数,也可以 ...

  2. HDU 2795 Billboard (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告;   然后给n个1*wi的广告,要求把广告贴 ...

  3. C#学习笔记(七):智能编译器

    自动实现属性 C#提供的set/get可以让我们很方便的使用属性,但是某些情况下书写还是稍微麻烦了点,如下: public class Test { private string _name; pub ...

  4. transition:all 0.5s linear;进度条动画效果 制作原理

    Html: <span class="progress"><b ><i></i></b><em>50< ...

  5. MFC实现数独(2)

    主要功能描述: 运行程序后对话框会显示一个9x9的待输入数独区域,并提供随机生成数独和生成数独按钮,生成数独按钮后会创建数独并随机显示其中一个至数独区域,随机生成数独会从已生成的数独中随机获取一个并显 ...

  6. C#全角半角转换函数

    Code#region 全角半角转换 /// <summary> /// 转全角的函数(SBC case) /// </summary> /// <param name= ...

  7. 用C++ 自娱自乐

    最无聊的时光当属 考试前的复习时段了,在一些论坛上看到一些用字符组成的图像,觉得有点意思,于是,自己 用C++ 参考一些论坛的图像,写了下面这个东西,来表达此时的心情. #include<ios ...

  8. Web.config之连接字介绍

    一.连接字配置方式 web.config中有两种方式来配置连接字:<appsetting>中配置,<connectionStrings>中配置. 1.<appsettin ...

  9. Flash Builder 4.6 界面显示一半中文一半英文?

    Flash Builder 4.6 (简称 Flex 4.6 或 FB 4.6)启动后界面有时候会显示一半中文,一半英文(这种奇葩的情况一般发生在 FB 4.6 刚安装后或操作系统安装一个类似 SP1 ...

  10. 下载discuz 6 论坛的附件

    前段时间我下了个python脚本把emsky的附件全部下载了,之前是因为偶然发现emsky附件不登陆也能访问,直接访问一个url就行了. 后来发现大部分discuz6的论坛都有这个bug,我想是因为d ...