【问题标题】:Not understood return behavior of recursive function with closure不理解带闭包的递归函数的返回行为
【发布时间】:2017-03-08 03:11:37
【问题描述】:

我的编程“技能”基础正在动摇。我不知道这种行为是由递归、闭包还是其他原因引起的,但这是迄今为止我见过的最奇怪的事情。

我的初衷是用递归来统计dom元素的父母。实现闭包以存储我的计数器,并且递归将为每个不等于 div#wrapper 的父级增加它。它有效 - 一次。对于第一个元素(只有 1 个父元素 - 它返回 1)但是第二次返回未定义。为了测试,我想出了这个装备:

let parents = countParents();
let pathLength = parents(3);

function countParents() {
    let counter = 0;
    return function nextParent(node) {
        let parent = node - 1;
        counter++;
        if (parent === 1)
            return 'WATAFAK';
        else
            nextParent(parent);
    }
}

console.log(pathLength);

其实我是在质疑自己的眼睛(已经很晚了,已经编程了一段时间了),但是这个函数返回 undefined。这怎么可能?

【问题讨论】:

  • else 分支中没有返回语句。
  • 另外,请用您正在使用的语言标记任何问题。

标签: recursion return closures


【解决方案1】:
function countParents() {
    let counter = 0;
    return function nextParent(node) {
        let parent = node - 1;
        counter++;
        if (parent === 1)
            return 'WATAFAK';
        else
            nextParent(parent); // call nextParent(parent) and throw away result
        return undefined;       // invisible line in every function
    }

    return undefined;           // invisible line in every function (never reached)
}

如果您希望递归的结果是结果,您必须在其前面添加return。现在它是怎样的,它只是为了副作用,它几乎是死代码。

由于else 分支不会返回所有函数在其块结束之前都有一个不可见的return undefined,

【讨论】:

  • 但是为什么当 parent 命中 1 时它不返回呢?有人会认为,一旦这个条件评估,递归与否 - 无关紧要,因为我们返回指定的值,在这种情况下是硬编码的 'WATAFAK'。事实上,我可以看到(在调试时)递归在返回行中断,当条件满足时,因为它返回,因此不再调用自己。
  • @Alex 确实如此。它返回给被调用者,它可以是没有返回的同一函数的实例。 return 不会返回全部,仅返回一个。想象一下在一个函数中有多个console.log('test')。如果返回确实也终止了被调用者,那么您只会看到一个输出,因为console.log 返回并且根据您的逻辑,调用它的函数也应该返回。要获得您想要的内容,您需要将默认大小写更改为 return nextParent(parent);,这样将返回来自 nextParent(parent) 的结果。
  • 所以递归行为是这背后的原因。现在你说隐藏返回,这是有道理的,因为当满足 if 条件时,我返回 'WATAFAK',但这只会返回到 nextParent 的前一个实例,它调用了这个实例,它自己又返回 undefined ,因为我没有另外指定。谢谢人:)
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2013-09-29
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多