美文网首页
【ES6 笔记】函数:尾调用优化

【ES6 笔记】函数:尾调用优化

作者: ___Jing___ | 来源:发表于2018-10-30 11:43 被阅读0次

    尾调用优化是ES6中在系统引擎优化上做的一个改进

    概念:尾调用指的是函数作为另一个函数的最后一条语句被调用

    function doSomething(){
      return doSomethingElse();
    };
    

    问题:在ES5中,尾调用的实现与其他函数调用实现类似:创建一个新的栈帧(stack frame),将其推入调用栈来表示函数调用。也就是说,在循环调用中,每一个未用完的栈帧都会被保存在内存中,当调用栈变得过大时会造成程序问题,也就是我们常说的栈溢出(stack overflow)。

    ES6中的尾调用优化

    如果满足以下条件,尾调用不再创建新的栈帧,而是清除并重用当前栈帧。

    • 尾调用不访问当前栈帧的变量(也就是说函数不是一个闭包);
    • 在函数内部,尾调用是最后一条语句;
    • 尾调用的结果作为函数值返回;

    合格示例:

    function doSomething(){
      return doSomethingElse();
    };
    

    以下是反面教材:

    function doSomething(){
      doSomethingElse(); //没有返回
    };
    
    function doSomething(){
      return 1+doSomethingElse(); //返回值后还需要做其他操作
    };
    
    function doSomething(){
      const result = doSomethingElse(); //函数调用不在尾部
      return result;
    };
    
    function doSomething(){
      const num = 1;
      const func = () => num //这是一个闭包函数,函数func需要访问局部变量num
      return func();
    };
    

    如何利用尾调用优化

    一般我们在优化函数的时候可能会用到尾调用优化,最常用的场景是在使用递归的时候:

    function factorial(n){
      if(n<=1){
        return 1;
      }else{
        return n*factorial(n-1); // 无法优化,函数返回后还需要再执行乘法操作
      }
    }
    

    优化后:

    function factorial( n, p=1 ){
      if(n<=1){
        return 1*p;
      }else{
        let result = n*p
        return factorial(n-1, result);
      }
    }
    

    相关文章

      网友评论

          本文标题:【ES6 笔记】函数:尾调用优化

          本文链接:https://www.haomeiwen.com/subject/ukawtqtx.html