es6函数之尾调用优化实例分析


Posted in Javascript onApril 25, 2020

本文实例讲述了es6函数之尾调用优化。分享给大家供大家参考,具体如下:

什么是尾调用优化?

尾调用是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。

function f(x) {
 return g(x)
}

上面代码中,函数f的最后一步是调用函数g,这就叫尾调用。

以下三种情况,都不属于尾调用。

// 情况一
function f(x) {
 let y = g(x)
 return y
}
// 情况二
function f(x) {
 return g(x) + 1
}
// 情况三
function f(x) {
 g(x)
}

尾调用不一定出现在函数尾部,只要是最后一步操作即可。

function f(x) {
 if (x > 0) {
  return m(x)
 }
 return n(x);
}

尾调用之所以与其他调用不同,就在于它的特殊的调用位置。

我们知道 ,函数调用会在内存形成一个“调用记录”,又称调用帧,保存调用位置和内部变量等信息。如果在函数A的内部调用了函数B,那么在A的调用帧上方还会形成一个B的调用帧。等到B运行结束,将结果返回A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成了一个调用栈。

尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置,内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。

function f() {
 let m = 1;
 let n = 2;
 return g(m + n);
}
f();

// 等同于
function f() {
 return g(3);
}
f();

// 等同于
g(3);

上面代码中,如果函数g不是尾调用,函数f就需要保存内部变量m和n的值、g的调用位置等信息。但由于调用g之后,函数f就结束了,所以执行到最后一步,完全可以删除f(x)的调用帧,只保留g(3)的调用帧。

这就叫做“尾调用优化”(Tail call optimization),即只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。这就是“尾调用优化”的意义。

注意,只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”。

function addOne(a){
 var one = 1;
 function inner(b){
  return b + one;
 }
 return inner(a);
}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js简单实现让文本框内容逐个字的显示出来
Oct 22 Javascript
Javascript核心读书有感之表达式和运算符
Feb 11 Javascript
JS实现在网页中弹出一个输入框的方法
Mar 03 Javascript
原生js实现图片轮播特效
Dec 18 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
Nov 22 Javascript
详解AngularJs路由之Ui-router-resolve(预加载)
Jun 13 Javascript
使用javascript做在线算法编程
May 25 Javascript
微信小程序 腾讯地图SDK 获取当前地址实现解析
Aug 12 Javascript
Servlet返回的数据js解析2种方法
Dec 12 Javascript
ES6对象操作实例详解
May 23 Javascript
javascript实现图片轮换动作方法
Aug 07 Javascript
antd design table更改某行数据的样式操作
Oct 31 Javascript
es6函数之尾递归用法实例分析
Apr 25 #Javascript
javascript 易错知识点实例小结
Apr 25 #Javascript
javascript执行上下文、变量对象实例分析
Apr 25 #Javascript
JavaScript ECMA-262-3 深入解析(二):变量对象实例详解
Apr 25 #Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
Apr 25 #Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
Apr 25 #Javascript
javascript 函数的暂停和恢复实例详解
Apr 25 #Javascript
You might like
PHP中数据类型转换的三种方式
2015/04/02 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
文本框input聚焦失焦样式实现代码
2012/10/12 Javascript
JS 操作Array数组的方法及属性实例解析
2014/01/08 Javascript
JavaScript 获取任一float型小数点后两位的小数
2014/06/30 Javascript
Node.js 的异步 IO 性能探讨
2014/10/08 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
2015/05/18 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
使用bat打开多个cmd窗口执行gulp、node
2017/02/17 Javascript
Vue3.0结合bootstrap创建多页面应用
2019/05/28 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
Python读写文件方法总结
2015/06/09 Python
在Python中pandas.DataFrame重置索引名称的实例
2018/11/06 Python
kafka-python批量发送数据的实例
2018/12/27 Python
Appium Python自动化测试之环境搭建的步骤
2019/01/23 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
加拿大著名时装品牌:SOIA & KYO
2016/08/23 全球购物
美国存储和组织商店:The Container Store
2017/08/16 全球购物
POS解决方案:MUNBYN(热敏打印机、条形码扫描仪)
2020/06/09 全球购物
DBA数据库管理员JAVA程序员架构师必看
2016/02/07 面试题
优秀毕业生自荐信范文
2014/01/01 职场文书
精通CAD能手自荐书
2014/01/31 职场文书
飘柔洗发水广告词
2014/03/14 职场文书
清明节网上祭英烈活动总结
2014/04/30 职场文书
护士节策划方案
2014/05/19 职场文书
世博会口号
2014/06/20 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
2014年依法行政工作总结
2014/11/19 职场文书
2014年节能工作总结
2014/12/18 职场文书
音乐之声观后感
2015/06/04 职场文书
母婴行业实体、电商模式全面解析
2019/08/01 职场文书
Nginx的反向代理实例详解
2021/03/31 Servers