JavaScript递归中的作用域问题?

在网上看到一个习题内容如下:

<body>
    <div class='div1'>
        <div class='div2'>
            <div class='div3'>
                <div class='div4'></div>
            </div>
        </div>
    </div>
    <script>
        function getNode(){
            var oDiv = document.getElementsByClassName('div4')[0];
            var parent = findNode(oDiv); 
            return parent;
        }
        function findNode(el){
            var rul = el.parentNode;
            
            if (!el || document.documentElement === rul || el === document.documentElement )
            {
                return;
            }else if (rul && rul.className === 'div1')
            {
                return rul;
            }else {
                return findNode(rul);
            }
        }
        var s1 = getNode();
        console.log(s1.className);
    </script>
 </body>

递归找出子节点最终的父节点。上边的代码可以得出正常的值;但是如果把

return findNode(rul);中参数改为return findNode(el);

就会报错:超过最大调用堆栈大小
问题:为什么会出现错误?

阅读 1.4k
2 个回答

在正常执行的时候,el这个东西是findNode的参数,是当前传递过来的元素
这个函数的意义在于,判断当前是否是div1了,如果不是,就去递归自己判断自己的父元素,
如果改成el的话,这个函数就永远递归判断自己了。

递归也是要有方向和结束条件的。
"超过最大调用堆栈大小"实际上就是函数发生无限递归了。因为递归过程中参数没有改变

按照你的写法,简化成下面这样。 看出来了吗?是个无限循环!递归是有“深度”限制的,超过就会报错:超过最大调用堆栈。 在V8引擎中,这个“深度”大小和堆栈以及堆栈帧(保存参数的局部变量)有关。

function findNode(el){
    return findNode(el);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题