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

递归函数

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

使用javascript书写递归函数

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

function fun(num){
if(num <= 1){
return 1;
} else{
return num * fun(--num);
}
}

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

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

呵呵,居然报错了

Uncaught TypeError: object is not a function

嗯,报了类型错误。。。

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

function fun(num){
if(num <= 1){
return 1;
} else{
return num * arguments.callee(--num);
}
}

然后测试一下:

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

OK,测试通过!

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

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(),那还是想想其他的方式吧。

看下面的代码:

var fun = (function f(num){
if(num <= 1){
return 1;
} else{
return num * f(--num);
}
});

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

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

参考资料

  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. SimpleUrlHandlerMapping用法

    SimpleUrlHandlerMapping是Spring MVC中适用性最强的Handler Mapping类,允许明确指定URL模式和Handler的映射关系.有两种方式声明SimpleUrlH ...

  2. VS~单步调试DLL

    有时我们从第三方下载DLL库之后,在使用VS进行调试时还是很麻烦的,现在我总结一下,在开发过过程中调试DLL的方法,希望对各位在开发中有帮助. 1 VS下载插件.Net Refector 2 引用你的 ...

  3. Js面向对象和数据类型内存分配(转)

    一 Js基本数据类型以及内存情况 1 Undefined Undefined类型只有一个值undefined,在使用了声明但未初始化的变量的时候,这个变量值就是undefined 1 var hi; ...

  4. 【灵感】wifi通过wifi发送优惠信息

    1.[灵感]wifi通过wifi发送优惠信息 http://content.businessvalue.com.cn/post/15362.html 2.手机彩票大爆发 http://content. ...

  5. URAL 2046 A - The First Day at School 模拟题

    A - The First Day at SchoolTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudg ...

  6. MyBatis之三:多表联合查询

    在这篇文章里面主要讲解如何在mybatis里面使用一对一.一对多.多表联合查询(类似视图)操作的例子. 注:阅读本文前请先大概看一下之前两篇文章. 一.表结构 班级表class,学生表student, ...

  7. android 关于提高第三方app的service优先级

    本博客仅仅要没有注明"转".那么均为原创,转贴请注明本博客链接链接 基本上大家都知道提高service优先级能够在非常大程度上让你的service免于由于内存不足而被kill,当然 ...

  8. 关于在android手机中腾讯、阿里产品不自定义虚拟键盘的想法

    1,自定义虚拟键盘,影响用户体验.你每个用户的喜好不一样,都有自己心仪的一款输入法.腾讯或是阿里设计出来的输入法很难满足上亿用户的喜好,到时候又是一场口水战,再说了就是专业的输入法肯定要比应用里嵌套的 ...

  9. 小米2及其他Android手机无法连接mac解决方案

    一般的android连接mac 很方便不用安装驱动就可以啦,可是不知道为什么二般情况下有的android手机(小米2,华为等)就是连接不上,下来就说说二般情况下如何连接. 1.关于本机-->更多 ...

  10. /proc/sys/net/ipv4/下各项的意义

        /proc/sys/net/ipv4/icmp_timeexceed_rate这个在traceroute时导致著名的“Solaris middle star”.这个文件控制发送ICMP Tim ...