为什么在递归中使用let replace var更好?

问题描述 投票:0回答:2

[当我尝试执行LeetCode问题25时,使用var无法通过,但使用let可以通过

var

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var reverseKGroup = function(head, k) {
    var p = head;
    var cur = head;
    var pre = null;
    for(var i=0; i< k; i++) {
        // 如果里面没走到最后就结束,则直接返回这部分链表 不需要再反转
        if(p == null) return head;
        p = p.next;
    }
    // 反转部分链表
    for(var j=0 ; i< k; i++) {
        var temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    // 此时的尾部即为一开始的头部,next 为接下来反转
    head.next = reverseKGroup(cur, k);
    return pre;
};

唯一的区别是使用“ var”或“ let”。

使用var将导致溢出。

Line 13 in solution.js
var reverseKGroup = function(head, k) {
                            ^
RangeError: Maximum call stack size exceeded

有人可以解释吗?

javascript recursion ecmascript-6 var let
2个回答
0
投票

这似乎是一个错误。 (var j = 0; i


0
投票

超出最大调用堆栈大小--- solution.js中的第13行有两种方法可以解决此问题。

For循环由于某些原因未在第13行终止...嗯,终止条件是第一个for循环中的iABOVE。

这里是let vs. const出现的地方。

您已经声明第二个for循环中使用的i与第一个for循环中的i相同(因为var i = 0)。

使用var立即提升变量,将其置于全局范围/词法上下文中。

将var更改为let在第二个循环的词法上下文中导致“引用i未定义”:

enter image description here

[每当执行javascript中的函数时,它就使用特定的“执行上下文”,该上下文包含将变量映射到值的词法环境/上下文。

函数执行上下文是根据调用时的位置而生的。在这种情况下,第二个for循环的执行上下文在其第一个循环上具有i = k的值,这是其停止条件。

最后,在第一个循环内,停止条件是前一个节点不为空。并且由于第二个for循环永远不会运行(键:它使用与第一个for循环相同的i值和相同的停止条件!),然后reverseKGroup(cur,k)将重复执行cur等于head的值,从而导致无穷大当head不为null时循环。

enter image description here

下面的代码通过了所有测试,只需在第二个循环中将i更改为j:

© www.soinside.com 2019 - 2024. All rights reserved.