【问题标题】:Is this type of recursion bad in JavaScript? If so, how should I rewrite it? [closed]这种类型的递归在 JavaScript 中是否不好?如果是这样,我应该如何重写它? [关闭]
【发布时间】:2015-05-22 13:17:29
【问题描述】:

我的 HTML 代码如下所示:

<body>
    <label for="change0">What is your favorite number?</label>
    <input type="text" id="change0" />
    <div id="addStuff"></div>

    <script src="scripts/main.js"></script>
</body>

我的 JS 看起来像这样:

/** @type {number} */
var counter = 1;

function doStuff(id) {
    var thing = document.getElementById(id);
    thing.addEventListener('change', doMoreStuff);
}

function doMoreStuff() {
    counter++;
    var addStuff = document.getElementById("addStuff");
    var stuff = document.createElement("input");
    stuff.id = "change" + counter;
    stuff.type = "text";
    addStuff.appendChild(stuff);
    doStuff(stuff.id);
}

window.onload = function() {
    /** @constant */
    var SEED_ID = "change0"
    doStuff(SEED_ID);
};

doMoreStuff() 函数递归调用 doStuff() 函数。 JavaScript 是否正确管理内存,还是我做错了?

【问题讨论】:

  • 如果 doStuff 确实调用了 doMoreStuff,您的代码将会崩溃。
  • 而不是将 ID 传递到您的 doStuff 函数中,您可以只传递元素。这意味着您根本不必为动态添加的input 元素赋予id 属性。 doStuff(document.getElementByID(SEED_ID)) 在您的 window.onload 中,然后在 doStuff(stuff) 在您的 doMoreStuff() 函数中。
  • 我想你不明白递归是什么意思。如果 doStuff 调用了 doStuff ,那么真正的递归调用是这样的,那么是的,您可能会遇到问题。您的代码没有任何问题,事实上,将您的代码分成多个函数调用是一种很好的编程习惯,因为这样更易于遵循和维护。
  • @russ - 我担心 doMoreStuff() 永远不会真正得到它的大括号,从而卸载内存。如果你有一个好的链接,我很想了解更多。谢谢!
  • doMoreStuff() 无法到达终点(右括号)的唯一原因是 doStuff() 中的某些内容出错。如果doStuff() 成功,则返回doMoreStuff()。由于doMoreStuff()在doStuff()之后没有更多的行,所以它返回到调用doMoreStuff()的地方。

标签: javascript


【解决方案1】:

doMoreStuff() 函数递归调用 doStuff() 函数。

这并不是真正的相互递归,因为 doStuff 不会调用 doMoreStuff - 它只是将其设置为要调用的处理程序。

JavaScript 是否正确管理内存

是的。异步“递归”(有时称为pseudo-recursion)不会增加调用堆栈,它很像尾递归。

【讨论】:

    【解决方案2】:

    你所拥有的不是递归。 doStuff 函数只是将事件处理程序绑定到事件,您可以在事件处理程序中重用该函数。

    它类似于递归,但等待事件发生会破坏链条。您需要考虑以与程序代码不同的方式处理事件,否则当您需要考虑多个不同的事件时会遇到困难。

    重用代码是一个很好的工具,但在这种情况下它的作用并不大。绑定事件的方式不是很相似,所以你可以在两个地方重复addEventListener调用,代码就更简单了:

    function doMoreStuff() {
        counter++;
        var addStuff = document.getElementById("addStuff");
        var stuff = document.createElement("input");
        stuff.id = "change" + counter;
        stuff.type = "text";
        addStuff.appendChild(stuff);
        stuff.addEventListener('change', doMoreStuff);
    }
    
    window.onload = function() {
        document.getElementById("change0").addEventListener('change', doMoreStuff);
    };
    

    【讨论】:

    • 很棒的建议,谢谢!
    猜你喜欢
    • 2021-05-24
    • 2013-12-12
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    相关资源
    最近更新 更多