递归函数的优化

本文作者:IMWeb 寒纱阁主 原文出处:IMWeb社区 未经同意,禁止转载

递归函数是一个函数自我调用而构成的,如下是一个典型的递归阶乘函数:

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

这个函数当然没有什么问题,但遇到下面的情况时,却出现了问题:

var newFactorial = factorial;
factorial=null;
alert(factorial(5));

此时会报错:

Exception: TypeError: factorial is not a function

为什么会出现这种问题呢?原因就出在return num*factorial(num-1)这一句上,这种写法使得函数太过紧密,一旦将函数保存到另一个变量中,并将原变量设置为null,factorial便不再是函数,因此会报错。

解决方法:arguments.callee

arguments.callee是一个指向正在执行的函数的指针,修改后代码如下:

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

这样就实现了更松散的耦合,解决了问题。

当然,还有另外一种方式:

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

上述方法创建了一个函数名为 f 的表达式,并将其赋值给factorial,这样一来即便将函数赋值给其他变量,函数名 f 依然有效。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏测试开发架构之路

堆和栈的区别

一、预备知识—程序的内存分配          一个由C/C++编译的程序占用的内存分为以下几个部分     1、栈区(stack)— 由编译器自动分配释放,存...

2858
来自专栏IT可乐

Spring详解(三)------DI依赖注入

  上一篇博客我们主要讲解了IOC控制反转,也就是说IOC 让程序员不在关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建、初始化、销毁等工作交给s...

1965
来自专栏一个小程序员的成长笔记

递归函数

这里使用的是命名函数表达式的方法实现递归,将这个函数赋值给 factorial 。这样即使在使用过程中对变量进行修改,也不会影响已赋值的递归函数进行调用,保证了...

501
来自专栏青玉伏案

iOS开发之Runtime常用示例总结

经常有小伙伴私下在Q上问一些关于Runtime的东西,问我有没有Runtime的相关博客,之前还真没正儿八经的总结过。之前只是在解析第三方框架源码时,聊过一些用...

1989
来自专栏北京马哥教育

搞定Linux Shell文本处理工具,看完这篇集锦就够了

Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替。既然是基本功,那就需要掌握,毕竟学习Shell脚本的过程中,还...

2412
来自专栏魂祭心

原 What Every Dev need

2828
来自专栏JavaEdge

开发人员必备Redis知识点基础命令键命令string命令hash结构listset结构sorted set

3106
来自专栏DOTNET

asp.net web api 异常捕获

1 向客户端发送错误消息 使用throw new HttpResponseException()向客户端抛出错误信息。 HttpResponseExceptio...

50112
来自专栏Java技术分享圈

Java的数据库连接工具类的编写

1064
来自专栏Java 源码分析

Bootstrap 源码分析

Netty 源码分析: Bootstrap 1. 结构 先看一个这个类的类层次结构, ? 好,这个结构还是比较明晰的,然后看他的主要字段,因为这些字段比较重...

3022

扫码关注云+社区