尾调用

作者: 想飞的雪糕 | 来源:发表于2021-12-24 16:26 被阅读0次

    在很多时候,递归算法能够解决很多问题,但是在以前它是一种以空间换取性能的办法,如果改成循环,往往理解起来会很困难,Javascript基于此进行了一种尾调用的优化,在满足如下条件时,会激活尾调用:

    1. 返回一个函数自调用

    2.传给递归函数的参数没有形成闭包;

    判断一个递归函数能否进行尾调用优化的最快方法:

    增加一个默认参数,看看能否用它来代表最终的结果 - holder

    优化前调用步骤:

    ● 计算实参表达式。

    ● 创建一个足以容纳函数所有形参和变量大小的新活跃对象(activationobject)。

    ● 将当前正在调用的函数引用存入新活跃对象。

    ● 将实参存入新活跃对象的实参列表,缺失的实参会被定义为undefined,而多余的实参则会被忽略。

    ● 将所有的变量都以undefined存入新活跃对象。

    ● 将新活跃对象中的next instruction field设置为函数执行完毕后需要立即执行的指令。

    ● 将当前活跃对象存入新活跃对象中的caller字段,要知道调用栈在JavaScript中只是一个概念,它实际上是活跃对象的链表。

    ● 将新活跃对象设为“当前活跃对象”。

    ● 开始执行被调用函数。

    优化后:

    ● 计算实参表达式。如果当前活跃对象足够大,

    则:● 直接把当前活跃对象设为新活跃对象。 --- 一般都到这里了,除非将之前的函数作用域加了引用形成闭包;

    否则:● 创建一个足以容纳函数所有形参和变量大小的新活跃对象;● 将当前活跃对象的caller字段直接赋值给新活跃对象;● 直接将新活跃对象设置为“当前活跃对象”。● 将当前正在调用的函数引用存入新活跃对象。● 将实参存入新活跃对象的实参列表,缺失的实参会被定义为undefined,而多余的实参则会被忽略。● 将所有的变量都以undefined存入新活跃对象。● 开始执行被调用函数。

    可以说js引擎对于算法的优化还是很关注的,比较越来越卷了

    相关文章

      网友评论

          本文标题:尾调用

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