zoukankan      html  css  js  c++  java
  • 尾调用

    学习阮一峰的《ECMAScript6 入门》的做的笔记,部分为个人理解,可能有误。

    ( 地址:https://es6.ruanyifeng.com/#docs/function#%E5%B0%BE%E8%B0%83%E7%94%A8%E4%BC%98%E5%8C%96

    尾调用是指某个函数最后一步调用另一个函数。

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

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

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

    非尾调用:

     1 function A(name){
     2   B(name);
     3   C(name);
     4   console.log( name+'03' );
     5 }
     6 function B( name ){
     7   console.log( name+'01' );
     8 }
     9 function C( name ){
    10   console.log( name+'02' );
    11 }
    12 A( 'xiaoxu' );

    执行结果:

    调用过程:

    调用A,

    在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。

     等到B运行结束,将结果返回到AB的调用帧才会消失。

    如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。

    C运行结束,

     A运行结束

     

    尾调用:

    function f() {
      let m = 1;
      let n = 2;
      return g(m + n);
    }
    function g( num ){
      return num;
    }
    console.log( f() );   //输出:3

    调用过程:

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

    调用 f

    f 执行到函数内最后一步

  • 相关阅读:
    Fix Installing .NET Framework 3.5 failed Error Code 0x800F0954 on Windows 10
    RHEL8安装五笔输入法
    Enable EPEL and Local Repository on RHEL8
    Why is Yum Replaced by DNF?
    检查Linux服务器是否被攻击的常用命令及方法
    IDEA 主题
    IDEA 如何显示一个类中所有的方法
    Appium 安装以及安装过程中遇到的问题
    Maven 如何发布 jar 包到 Nexus 私库
    java泛型的基本使用
  • 原文地址:https://www.cnblogs.com/xiaoxuStudy/p/12629829.html
Copyright © 2011-2022 走看看