【问题标题】:JavaScript Module Pattern across multiple files跨多个文件的 JavaScript 模块模式
【发布时间】:2015-07-04 16:40:59
【问题描述】:

我不得不重组一些古老的代码,而且在许多不同的文件中都有相当多的代码。该方法是使用揭示模块模式,如JavaScript Module Pattern: In-Depth(Cross-File Private State 部分)中所述。

第一个函数表达式效果很好,我可以在 Firebug 中看到函数组件也在第二个块中正确分配。但随后变量突然变为未定义。

我整理了一个简化的example,控制台显示第二次赋值后变量未定义。

var test = (function ($, ns, undefined)
{
    function test1()
    {
        console.log("executing test1");
        ns.testx.test2();
    }
    return { test1: test1 };
}(jQuery, test || {}));

console.log(test);

var test = (function ($, ns, undefined)
{
    ns.testx = (function ()
    {
        function test2()
        {
        console.log("executing test2");
        }
        return { test2: test2 }
    })();
}(jQuery, test || {}));

console.log(test);

// DOM ready
$(function ()
{
    test.test1();
});

几个变体,例如在顶部只定义一次变量也不起作用。如果交换两个函数表达式,则执行测试 1,但 ns.testx 未定义。

我担心我错过了令人眼花缭乱的显而易见的事情,并且真的很想了解为什么这不起作用。我还需要让它工作,因此非常感谢任何帮助(将文件合并为一个不是一种选择)。

【问题讨论】:

    标签: closures


    【解决方案1】:

    试试

    var test = (function ($, ns, undefined)
    {
        function test1()
        {
            console.log("executing test1");
            ns.testx.test2();
        }
        ns.test1 = test1;
        return ns;
    }(jQuery, test || {}));
    
    console.log(test);
    
    var test = (function ($, ns, undefined)
    {
        ns.testx = (function ()
        {
            function test2()
            {
            console.log("executing test2");
            }
            return { test2: test2 }
        })();
    
        return ns;
        /*
          This will be
          {
            test1: test1,
            testx: {
              test2: test2
            }
          }
        */
    }(jQuery, test || {}));
    

    【讨论】:

    • 谢谢,它有效,事实上我曾短暂考虑过尝试这样的事情,但由于以下原因而放弃了这个想法:据我所知,ns 是一个通过引用传递的对象;因此,应该可以在不必返回 ns 的情况下进行分配;在我将此标记为已回答之前,您能否解释一下为什么 ns 范围仅限于函数/为什么必须返回 ns?
    • 如你所说,对象是通过引用传递的。问题是您在第二个“var test = ...”上为其分配了一个新值。如果您避免了该变量赋值(仅删除“var test = ..”并仅使用自可执行函数),即使您删除了其中的“return ns”语句,它也会起作用。
    • 谢谢 - 出于好奇,我只是在没有返回语句的情况下运行它,但它不起作用;所以我仍然不完全清楚为什么需要它。无论如何,我标记了您的答案,因为它帮助我解决了问题。
    • 如果您在第一部分中取出退货,它不会 - 那么为什么需要一个而不是另一个呢?它也应该只是第一部分的参考。
    • 因为在第一部分中刚刚声明了对象。做 var test = ... 和做 var test; 是一样的。 test = ...(检查变量提升)。因此,在这种情况下,在您为其赋值之前,测试是未定义的。
    猜你喜欢
    • 2014-05-01
    • 2012-08-15
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 2018-02-14
    • 1970-01-01
    相关资源
    最近更新 更多