为了账号安全,请及时绑定邮箱和手机立即绑定

尾部调用优化时候遇到的问题

尾部调用优化时候遇到的问题

江户川乱折腾 2018-12-27 22:19:15
在看阮一峰老师的es6,在尾部调用优化那一节,我对文章中提到的我们知道,函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。这两段话并不能很好的理解,有哪位大神能解释解释
查看完整描述

1 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

talk is weak


A:


function fomatSum(val){

    return 'sum / 2 =' + val/2 ;

}

function comp(x,y){

    var sum = x + y;

    return fomatSum(sum);

}

comp(2,4);

B:


function fomatSum(val){

    return 'sum / 2 =' + val/2 ;

}

function comp(x,y){

    var sum = x + y;

    var result = fomatSum(sum);

    return result;

}    


comp(2,4);

A、B两种写法都能得到相同的结果:sum / 2 = 3


在A中,当程序运行到return fomatSum的时候,此时comp函数已经做完了它该做的事情,只需要呼叫comp做接下来的事情。相当于接力赛,comp把接力棒(传入所需参数)给fomatSum后,comp就可以休息了(释放掉),故不需要comp的调用帧。

在B中,当程序运行到fomatSum函数的时候,就跑去执行fomatSum了,但是需要返回值给result(这时候就需要通过调用帧 回到comp函数中),然后return这个值。相当于餐馆点餐,服务员comp把菜单(传入所需参数)给厨师fomatSum后,comp还需要等待fomatSum把东西做好,再给顾客上餐,所以需要调用帧去找到服务员comp。

关于尾调用以及尾递归,建议配合 上下文 进行理解其目的和意义,这里有我之前写的一篇文章 从async await 报错Unexpected identifier 谈谈对上下文的理解 ,可以只看结尾对上下文的分析,希望有帮助。


查看完整回答
反对 回复 2019-01-25
  • 1 回答
  • 0 关注
  • 327 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信