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 限制输入和粘贴(IE,firefox测试通过)
Nov 14 Javascript
基于jquery实现后台左侧菜单点击上下滑动显示
Apr 11 Javascript
sails框架的学习指南
Dec 22 Javascript
JavaScript中数据结构与算法(三):链表
Jun 19 Javascript
js贪吃蛇网页版游戏特效代码分享(挑战十关)
Aug 24 Javascript
Kendo Grid editing 自定义验证报错提示的解决方法
Nov 18 Javascript
浅谈js中的变量名和函数名重名
Feb 13 Javascript
AngularJS 单选框及多选框的双向动态绑定
Apr 20 Javascript
深入理解Angularjs中$http.post与$.post
May 19 Javascript
tween.js缓动补间动画算法示例
Feb 13 Javascript
vue集成chart.js的实现方法
Aug 20 Javascript
浅谈JSON5解决了JSON的两大痛点
Dec 14 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将DateTime对象转化为友好时间显示的实现代码
2011/09/20 PHP
php定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
图片格式的JavaScript和CSS速查手册
2007/08/20 Javascript
jQuery 回车事件enter使用示例
2014/02/18 Javascript
常用jQuery选择器总结
2014/07/11 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
JavaScript函数内部属性和函数方法实例详解
2016/03/17 Javascript
浅析BootStrap栅格系统
2016/06/07 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
基于Vue单文件组件详解
2017/09/15 Javascript
JavaScript实现区块链
2018/03/14 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
JavaScript创建对象方式总结【工厂模式、构造函数模式、原型模式等】
2018/12/19 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
2019/06/07 Javascript
JavaScript canvas仿代码流瀑布
2020/02/10 Javascript
jQuery 选择方法及$(this)用法实例分析
2020/05/19 jQuery
详解JavaScript数据类型和判断方法
2020/09/04 Javascript
Vue路由 重定向和别名的区别说明
2020/09/09 Javascript
[03:23]我的刀塔你不可能这么可爱 第一期金萌萌的故事
2014/06/20 DOTA
sqlalchemy对象转dict的示例
2014/04/22 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
2019/08/12 Python
对python中的*args与**kwgs的含义与作用详解
2019/08/28 Python
Python实现生成密码字典的方法示例
2019/09/02 Python
html5 canvas里绘制椭圆并保持线条粗细均匀的技巧
2013/03/25 HTML / CSS
Book Depository澳大利亚:世界领先的专业在线书店之一
2018/12/27 全球购物
请写出 BOOL flag 与"零值"比较的 if 语句
2016/02/29 面试题
什么是Linux虚拟文件系统VFS
2015/08/25 面试题
乡镇纠风工作实施方案
2014/03/22 职场文书
食品销售计划书
2014/04/26 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
课前一分钟演讲稿
2014/08/26 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
2014年社区工作总结
2014/11/18 职场文书