【问题标题】:Javascript Module UsageJavascript 模块使用
【发布时间】:2016-04-20 07:05:47
【问题描述】:

我刚刚开始使用 javascript 模块,我想确保我做得正确。

下面是我所遵循的方法的一个示例,基于我读到的关于 here 的“松散增强模式”

    //myApp.js
    var myApp = {};


    //someModule1.js
    (function (ma) {
        ma.someModule1.DoStuff = function () {
            alert("hi");
        };
        return ma;
    }(myApp || {}));


    //someModule2.js
    (function (ma) {
        ma.someModule2.DoMoreStuff = function () {
            alert("ho");
        };
        return ma;
    }(myApp || {}));


    //someModule3.js
    myApp.someModule1.DoStuff();
    myApp.someModule2.DoMoreStuff();

myApp.js 中的 myApp 变量将是唯一全局公开的变量,所有其他模块及其功能只能通过此变量访问。

someModule3.js 不一定是一个模块,而是任何想要访问 myApp 对象属性的任意 javascript(在定义了适当的模块之后)。

我不是 100% 清楚的部分是:(myApp || {}, jQuery) 那部分是什么,它到底在做什么(我知道整个事情是一个闭包,但我只是不明白最后一部分是如何工作的)? 看起来“ma”最初什么都不是,我在闭包的主体中添加了一个函数,然后返回 ma。此时myApp只有一个功能。

在结尾处 (myApp || {}),它实际上是在说“ma 不是什么,它实际上被称为 myApp,如果它存在,我会将这些函数附加到该对象。”

这是对的还是我错了?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    我看到四个问题:

    1. 您的代码不会按原样运行。您必须先定义.someModule1,然后才能分配给它。

    2. 没有理由使用return ma,因为您没有使用返回值。

    3. 没有理由传递myApp || {},因为如果未定义myApp,那么您的代码将不会执行任何操作,因为您创建的对象不会被任何变量捕获,只会立即被垃圾收集而不是可以访问。

    4. 正如您所展示的代码,您包含代码的 IIFE 除了增加代码行数和复杂性外,并没有做任何事情。

    这里有关于每个问题的更多详细信息。

    您的模块不会按原样运行。您需要通过更改它来定义.someModule1,并且您的代码中没有理由传递myApp || {}

    //someModule1.js
    (function (ma) {
        ma.someModule1.DoStuff = function () {
            alert("hi");
        };
        return ma;
    }(myApp || {}));
    

    到这里:

    //someModule1.js
    (function (ma) {
        // you must define .someModule1 before you can assign properties to it
        ma.someModule1 = {};
        ma.someModule1.DoStuff = function () {
            alert("hi");
        };
        return ma;
    }(myApp));
    

    也没有理由在您的代码中使用return ma,因为您没有使用返回值。

    myApp || {} 在这里没有价值的原因是因为如果 myApp 没有定义,那么你的模块中的任何代码都不会做任何有用的事情,因为你要分配东西的底层对象没有被捕获在变量中任何地方。因此,如果未定义 myApp,那么您的代码将一事无成。因此,在某种程度上,通过定义,myApp 必须已经定义为您的代码有用,因此,您可以将myApp 传递到 IIFE。


    正如您所展示的代码,将属性分配放在 IIFE 中没有任何好处或理由。 IIFE 中没有任何闭包变量或任何私有的东西。因此,您将获得完全相同的结果:

    myApp.someModule1 = {};
    myApp.someModule1.DoStuff = function () {
        alert("hi");
    };
    

    使用 IIFE 有一些原因,但您在此代码示例中没有显示任何原因。就我个人而言,我喜欢使用最简单的代码来实现您的目标,而不是仅仅为了它而增加额外的复杂性。其他人喜欢将他们所有的代码放在这些 IIFE 模块中。只有在确实有理由将代码放入 IIFE 时,我才会将代码放入 IIFE。

    【讨论】:

    • 谢谢,这是一个很好的解释,我会将其标记为答案。我搞砸了没有定义 .someModule1 位,我最初没有它,但是在我已经用 myApp.DoStuff() 测试过它之后添加了它,很抱歉造成混淆。想要使用 IIFE 的原因是因为我可能会在某些时候使用一些我不想泄漏到全局范围内的变量(但你是对的,我的示例没有显示)。
    猜你喜欢
    • 1970-01-01
    • 2019-09-04
    • 2018-05-28
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多