【问题标题】:revealing module pattern and timeout揭示模块模式和超时
【发布时间】:2023-04-03 00:42:02
【问题描述】:

我想知道是否有人可以给我一个简单的解决方案。

我想让两个狗实例重复吠叫 + 摇尾组合。

如果所有逻辑都包含在 barkNameAndTime 函数中,我很好,但是通过 setTimout 调用 wagTail 我会丢失上下文。我写的 JS 不多,所以我的闭包知识有点生锈,我似乎无法找到一个干净的解决方案。

问题是,Baloo 最终会吠叫和摇尾巴,而 Lola 迷失在人群中 :)

谢谢 沃里克

<script type="text/javascript">
$(document).ready(function () {
    var zDog1 = new dog("Lola");
    var zDog2 = new dog("Baloo");

    zDog1.bark();
    zDog2.bark();
});

function dog(aName) {
    var name = aName,
        barkNameAndTime = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
            setTimeout(wagTail, 1000);
        };

        wagTail = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
            setTimeout(barkNameAndTime, 1000);
        }

    return {
        bark: barkNameAndTime
    };
}

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    在您的实现中,wagTail 是一个全局变量(可能是错误的),因此每次您创建一个新的狗对象时,它的一个全局值和上下文都会被替换。

    如果您将其设为局部变量(通过将一个分号更改为逗号),它应该可以工作。

    function dog(aName) {
        var name = aName,
            barkNameAndTime = function () {
                var time = new Date().getTime();
                $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
                setTimeout(wagTail, 1000);
            }, 
    
            wagTail = function () {
                var time = new Date().getTime();
                $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
                setTimeout(barkNameAndTime, 1000);
            }
    
        return {
            bark: barkNameAndTime
        };
    }
    

    当它是一个局部变量时,wagTail 的每个副本都会保留自己的闭包上下文(因此可以访问同一堆栈帧中的局部变量)。当它是一个全局变量时,所有对wagTail 的调用都将具有相同的上下文,这将是上次分配给它的上下文。

    仅供参考,这是我不喜欢这种在存在多行初始化程序时声明局部变量的方式的原因之一,因为一个微妙的错字会呈现其中一些隐式全局变量。我宁愿预先声明当地人,然后在正文中分配给他们。遭受此错误的可能性要小得多。或者,在这种情况下,您不需要使用变量语法,您可以将 barkNameAndTimewagTail 声明为本地函数(Bergi 添加的代码示例):

    function dog(name) {
        function barkNameAndTime() {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
            setTimeout(wagTail, 1000);
        }
        function wagTail() {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
            setTimeout(barkNameAndTime, 1000);
        }
    
        return {
            bark: barkNameAndTime
        };
    }
    

    【讨论】:

    • 哇,很好看。我已经盯着那个愚蠢的东西看了一段时间了。非常感谢!
    • @Bergi - 感谢添加本地功能版本。这就是我所说的概念。我可能会将wagTail 设为匿名函数,因为它没有理由拥有名称。
    • 我宁愿说没有理由function to have no name :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多