• 徐承银
    2019-08-22
    不进栈,就不会栈溢出了。function runStack (n) {
      if (n === 0) return 100;
      return setTimeout(function(){runStack( n- 2)},0);
    }
    runStack(50000)
     1
     12
  • ytd
    2019-08-22
    改成循环不会栈溢出了,不过就有可能陷入死循环:
    // 优化
    function runStack(n) {
        while (true) {
            if (n === 0) {
                return 100;
            }

            if (n === 1) { // 防止陷入死循环
                return 200;
            }

            n = n - 2;
        }
    }

    console.log(runStack(50000));
    展开
    
     9
  • Ryan
    2019-09-03
    https://kangax.github.io/compat-table/es6/ 这个网站可以看到各平台对作为es6特性的尾调用优化的支持情况,表格里面显示:桌面浏览器中只有safari 12 支持尾调用优化。我自己使用safari 12测试,严格模式下运行作者代码能正常得出结果。https://node.green/#ESNEXT-strawman--stage-0--syntactic-tail-calls 这个网站则显示,目前版本的node.js不支持尾递归优化
    
     5
  • 一步
    2019-08-24
    关于调用栈的大小,不用的平台,比如浏览器,nodejs 怎么查看设置的,还是硬编码的?

    作者回复: 调用栈有两个指标,最大栈容量和最大调用深度,满足其中任意一个就会栈溢出,不过具体多大和多深,这个没有研究过,你可以拿我留的作业那段代码去各平台测试下,应该很快就能测试出来最大调用深度。

    
     5
  • mfist
    2019-08-22
    1. 改成尾递归调用(需要在严格模式下面生效)
    function runStack (n, result=100) {
      if (n === 0) return result;
      return runStack( n- 2, result);
    }
    runStack(50000, 100)
    2. 改成循环调用,不使用递归函数,就不存在堆栈溢出
    展开

    作者回复: 有尝试过尾优化会生效吗?

     5
     5
  • melon
    2019-10-17
    老师没有提函数的入参和返回值,函数的入参和返回值是不是也在函数上下文的变量环境里呢?
     1
     4
  • pyhhou
    2019-08-23
    思考题当中的函数,如果输入参数是正偶数,那么不管数值多大,最后结果都是 100,除此之外,如果输入参数是负数或者是正奇数,甚至说是浮点数,那么使用递归方式调用会导致栈溢出,使用循环方式去实现会导致死循环,如果仅仅是基于当前的输入参数(50000)改写的话:
    function runStack (n) {
      return 100;
    }
    runStack(50000);

    当然也可以把递归改成循环的写法,但是要注意的是这时的输入参数仅限定于正偶数,否则会死循环:
    function runStack (n) {
      while (n !== 0) {
        n -= 2;
      }

      return 100;
    }
    runStack(50000);
    展开

    作者回复: 可能我的题目出得不太好,误解我出题目的意思了,我的意思是runStack要执行50000次的,但是要避免栈溢出,改成斐波那契数列的列子可能好点。

    
     4
  • 黄晓杰
    2019-09-11
    老师,我有一个疑问,调用栈是后进先出,那么当存在闭包时,某个函数的执行上下文还存在,那么其他函数的出栈是否受影响?

    作者回复: 执行上下文已经没了,只不过内部函数引用的变量还保存在堆上,所以不影响栈的操作,后面一节有分析这个问题!

    
     3
  • Geek_8476da
    2019-09-10
    我测试出了栈的深度为12574
     2
     3
  • yetta_xy
    2019-09-07
    老师您好,有个疑问。
    addAll函数中的result变量没有用var声明,直接赋值的,这个变量应该存在于全局上下文的环境变量对象中吧?
     1
     3
  • AICC
    2019-08-27
    老师会在什么地方讲解每节内容留下的思考题?比如像这节的尾调用问题,是否存在尾调用优化,至少目前看到的尝试方式在chrome上都会出现栈溢出,有说是v8移除了TCO,即尾调用优化,参考:https://stackoverflow.com/questions/42788139/es6-tail-recursion-optimisation-stack-overflow
    还有目前google提供的优化方式,但在chrome上目前还不支持,如下
    function factorial(n, acc = 1) {
      if (n === 1) return acc;
      return continue factorial(n - 1, acc * n)
    }
    展开
    
     2
  • 许童童
    2019-08-22
    将递归改成迭代就好了,还可以使用尾递归优化。感觉老师这道题改成斐波那契数列会更好。

    function runStack (n) {
      while (n > 0) {
        n -= 2
      }
      return 100
    }
    runStack(50000)
    展开

    作者回复: 是的 改成斐波那契数列会好点。

    不过尾部优化似乎是没效果的

     3
     2
  • 曾侃
    2019-09-30
    老师好,第三张图函数调用过程是不是有点问题,函数的可执行代码里面是不是应该包含 b = 10?
    
     1
  • 轩爷
    2019-09-15
    亲测,Chrome【版本 77.0.3865.75(正式版本)(64 位)】和Firefox【67.0.4 (64 位)】都不支持尾调用优化,只有Safari【版本 12.1.2 (14607.3.9)】支持
    
     1
  • 郭纯
    2019-09-04
    解决这样的问题 有几种方法 比如 不用递归 用循环 采用延时执行.最好的方法采用生成器 generator 参考协同的实现.
    
     1
  • 安思科
    2019-08-23
    就您说的只要把递归的那个return用setTimeout包一下就行了吧
    
     1
  • 忘忧草的约定
    2019-08-22
    我理解将内部的函数当成一个独立的子任务放到microstack任务队列里面去就可以了吧,这样当该任务执行的时候调用栈里面只有全局上下文
    
     1
  • 爱吃锅巴的沐泡
    2019-08-22
    老师,有两个问题:
    1、老师在文中写到“首先,从全局执行上下文中,取出 add 函数代码。”,这里是取到函数的引用,还是整个函数代码,函数的存储是怎样的?
    2、声明带参的函数并调用的编译过程是怎样的,参数应该是和arguments有关吧,老师能详细说一下编译过程嘛?

    作者回复: 第一个:看成是一个引用,函数实体是保存到堆中的。堆栈结构后面章节会介绍。

    第二个:如果一个函数带有参数,编译过程中,参数会通过参数列表保存到变量环境中

    
     1
  • Marvin
    2019-08-22
    这个代码运行情况依赖入参,有三种情况:1、n=0,返回100;2、n为正偶数,递归n/2次之后返回100;3、n为非上述情况,栈溢出。优化方案:判断参数n,1、2两种情况返回100,3的情况抛错。
     1
     1
  • Hurry
    2019-08-22
    将递归,改成循环:
    ```
    function runStack(n) {
            if (n === 0)
                return 100;
        }

        function run(n) {
            while (n > 0) {
                runStack(n)
                n = n - 2;
            }

            return runStack(n)
        }

        run(50000)
    ```
    展开
    
     1
我们在线,来聊聊吧