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

 更新时间:2020年04月25日 13:27:10   作者:wangliang_001  
这篇文章主要介绍了es6函数之尾调用优化,结合实例形式分析了es6函数尾调用优化相关功能、原理、实现方法及操作注意事项,需要的朋友可以参考下

本文实例讲述了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.jb51.net/code/HtmlJsRun测试上述代码运行效果。

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

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

您可能感兴趣的文章:

相关文章

  • 老生常谈document.ready和window.onload

    老生常谈document.ready和window.onload

    这篇文章主要介绍了document.ready和window.onload的相关知识,包括document.ready和window.onload的区别,要使用document.ready()或者document.onload()的原因分析,本文结合实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2024-01-01
  • JavaScript生成的动态下雨背景效果实现方法

    JavaScript生成的动态下雨背景效果实现方法

    这篇文章主要介绍了JavaScript生成的动态下雨背景效果实现方法,通过自定义函数实现动态背景效果,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • JS区分浏览器页面是刷新还是关闭

    JS区分浏览器页面是刷新还是关闭

    在web开发中我们经常各种各样的需求。今天小编给大家介绍JS区分浏览器页面是刷新还是关闭标签页,非常实用,感兴趣的童鞋参考下吧
    2016-04-04
  • 对于JavaScript继承你到底了解多少

    对于JavaScript继承你到底了解多少

    js的继承机制不同于传统的面向对象语言,采用原型链实现继承,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法,下面这篇文章主要给大家介绍了关于JS继承的相关资料,需要的朋友可以参考下
    2021-09-09
  • JS解决移动web开发手机输入框弹出的问题

    JS解决移动web开发手机输入框弹出的问题

    在移动web开发中和pc端不同的是,手机的输入是软键盘,这样就会有个问题,那就是当有输入的时候,键盘弹起来,整个页面难免会发生变化。怎么解决这个问题呢?下面脚本之家小编给大家分享JS解决移动web开发手机输入框弹出的问题
    2017-03-03
  • js用类封装pop弹窗组件

    js用类封装pop弹窗组件

    这篇文章主要为大家详细介绍了js用类封装pop弹窗组件的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • require导入module.exports 或 exports导出的使用方法

    require导入module.exports 或 exports导出的使用方法

    module.exports用于导出整个模块的内容,可以通过赋值给 module.exports 导出一个对象、函数或值,导出的内容可以被其他模块通过require 导入,本文给大家介绍require导入module.exports 或 exports导出的使用,感兴趣的朋友一起看看吧
    2023-11-11
  • 一步步教你用js简单实现新年倒计时

    一步步教你用js简单实现新年倒计时

    一转眼已经腊月了,相信小伙伴们一定想知道我们距离2023新年还有多少天,下面这篇文章主要给大家介绍了关于如何一步步教你用js简单实现新年倒计时的相关资料,需要的朋友可以参考下
    2022-12-12
  • 利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换

    利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换

    这篇文章主要介绍了利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换,非常具有实用价值,需要的朋友可以参考下。
    2017-01-01
  • 小程序中this.setData的使用和注意事项

    小程序中this.setData的使用和注意事项

    这篇文章主要介绍了微信小程序中this.setData的使用和注意事项,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论