Javascript 实现匿名递归的实例代码


Posted in Javascript onMay 25, 2017

递归是一种常见的编程技巧,实名递归相信大家都不陌生,但如果想要实现匿名递归呢?比如想要返回一个匿名递归函数,又或者是定义一个匿名递归函数并直接调用它,该怎样去做呢?本文将来探讨一下它的实现。

实名递归

我们还是先从实名递归说起吧,还是用那个最简单的求阶乘的例子:

function fact(n) {
 if (n < 2) {
  return n;
 } else {
  return n * fact(n - 1);
 }
}
console.log(fact(5));

递归要求自己调用自己,如果函数有名字,这就太简单不过了。

利用变量实现递归

函数还可以赋给一个变量,不过要实现递归,函数体里面还是要依赖这个变量名:

var f = function(n) {
 if (n < 2) {
  return n;
 } else {
  return n * f(n - 1);
 }
}
console.log(f(5));

应该说这种方式跟之前的其实没有本质的不同。

匿名递归

现在我们来探讨匿名递归的实现。

初步设想

如果想要返回一个匿名递归函数,又或者是定义一个匿名递归函数并直接调用它:

(function (n) {
 if (n < 2) {
  return n;
 } else {
  return n * ?(n - 1);
 }
})(5);

如果没有一个名字,代码中那个问号我们就不知道要填写什么,就没法形成递归了,此时我们要怎么办呢?这时就要请出 arguments 对象了。

arguments 对象

在 javascript 的函数中,arguments 对象代表了实际调用时的参数对象。在我们的递归函数中,实际上我们也可以完全不用去定义“形式参数” n:

function factNoParam() {
 if (arguments[0] < 2) {
  return arguments[0];
 } else {
  return arguments[0] * factNoParam(arguments[0] - 1);
 }
}
console.log(factNoParam(5));

只要我们在调用时传入了实际的参数,就可以用 arguments[0] 取得实际传入的这个参数的值。

如果有更多的参数,还可以 arguments[1],arguments[2] 等来取得。

arguments.callee 属性

arguments 可以用来获取参数,相信你可能已经知道了,但 arguments 对象其实还有一个属性,即所谓的 callee。arguments.callee 代表了这个函数本身。这是什么意思呢?其实我们完全可以把 fact 写成这样:

function fact(n) {
 if (n < 2) {
  return n;
 } else {
  return n * arguments.callee(n - 1);
 }
}
console.log(fact(5));

那么它依然是递归的。因为 arguments.callee 实际就等于 fact。

那么,到了这里,有了这个属性的帮助,要实现匿名递归就不难了,只要把 ? 改为 arguments.callee 即可:

(function (n) {
 if (n < 2) {
  return n;
 } else {
  return n * arguments.callee(n - 1);
 }
})(5);

如果有需要,也可以把它作为匿名递归返回。

关于 javascript 实现匿名递归的介绍就到这里。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 判断中文字符长度的函数代码
Aug 27 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
Dec 25 Javascript
JavaScript中的值是按值传递还是按引用传递问题探讨
Jan 30 Javascript
jQuery实现切换页面过渡动画效果
Oct 29 Javascript
JavaScript面向对象程序设计教程
Mar 29 Javascript
JS基于clipBoard.js插件实现剪切、复制、粘贴
May 03 Javascript
jQuery中设置form表单中action值的实现方法
May 25 Javascript
AngularJS 最常用的八种功能(基础知识)
Jun 26 Javascript
JavaScript原型继承_动力节点Java学院整理
Jun 30 Javascript
vue使用vue-cli快速创建工程
Jul 28 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
Dec 29 jQuery
微信小程序非跳转式组件授权登录的方法示例
May 22 Javascript
Kotlin学习第一步 kotlin语法特性
May 25 #Javascript
jQuery Masonry瀑布流布局神器使用详解
May 25 #jQuery
jQuery模拟实现天猫购物车动画效果实例代码
May 25 #jQuery
jquery.masonry瀑布流效果
May 25 #jQuery
Node.js操作redis实现添加查询功能
May 25 #Javascript
浅谈struts1 &amp; jquery form 文件异步上传
May 25 #jQuery
详解Vue中过度动画效果应用
May 25 #Javascript
You might like
php 前一天或后一天的日期
2008/06/28 PHP
用PHP实现弹出消息提示框的两种方法
2013/12/17 PHP
微信公众平台开发关注及取消关注事件的方法
2014/12/23 PHP
php实现用于计算执行时间的类实例
2015/04/18 PHP
PHP设计模式之策略模式原理与用法实例分析
2019/04/04 PHP
深入认识javascript中的eval函数
2009/11/02 Javascript
JSON传递bool类型数据的处理方式介绍
2013/09/18 Javascript
微信小程序 本地数据存储实例详解
2017/04/13 Javascript
JavaScript学习笔记之函数记忆
2017/09/06 Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
JS中FileReader类实现文件上传及时预览功能
2020/03/27 Javascript
vue实现路由懒加载的3种方法示例
2020/09/01 Javascript
vue+axios 拦截器实现统一token的案例
2020/09/11 Javascript
js获取url页面id,也就是最后的数字文件名
2020/09/25 Javascript
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
Python操作MySQL简单实现方法
2015/01/26 Python
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
python 实现tar文件压缩解压的实例详解
2017/08/20 Python
Python实现返回数组中第i小元素的方法示例
2017/12/04 Python
django orm 通过related_name反向查询的方法
2018/12/15 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
2019/04/28 Python
Django web框架使用url path name详解
2019/04/29 Python
在Django admin中编辑ManyToManyField的实现方法
2019/08/09 Python
linux mint中搜狗输入法导致pycharm卡死的问题
2020/10/28 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
css3实现六边形边框的实例代码
2019/05/24 HTML / CSS
数据库基础的一些面试题
2012/02/25 面试题
MYSQL支持事务吗
2013/08/09 面试题
会计专业毕业生自我鉴定
2013/10/29 职场文书
银行见习期自我鉴定
2014/01/29 职场文书
网络工程专业自荐信范文
2014/03/16 职场文书
一位农村小子的自荐信
2014/04/07 职场文书
村班子对照检查材料
2014/08/18 职场文书
新学期红领巾广播稿
2014/10/04 职场文书
人事专员岗位职责
2015/02/03 职场文书
出国导师推荐信
2015/03/25 职场文书