2

只是想知道这是否是一个好的 JavaScript 实践。

假设我有许多网页都调用初始化函数“init()”,每次加载脚本时在我的模式中使用IIFE来运行该函数是否正确?

var foo = (function() {
    var bar = "something";

    (function init() {
        // Do something crazy that's gonna be the same across all my web pages
        // like adding an event listener or something
        // ...
        document.write('page init...');
    }());

    function privatePage1() {
        // This stuff is gonna be used only in page1.html via foo.privatePage1
        document.write('page 1' + bar);
    }

    function privatePage2() {
        // This stuff is gonna be used only in page2.html via foo.privatePage2
        document.write('page 2' + bar);
    }

    return {
        privatePage1: privatePage1,
        privatePage2: privatePage2
    }
}());
4

2 回答 2

6

这是一个非常主观的领域,但这是我的看法:

  • 当您使用模块模式时,您正在为其余代码提供一组包含的功能。它本质上是一个迷你图书馆。

  • 一般来说,我不希望库在加载它时任何事情,除了完全在库内部的初始化步骤(例如设置配置、实例化一些必要的对象等)——实际上没有任何影响DOM 或以其他方式显着改变环境(这就是为什么我对更改基本对象原型的 Date.js 或 Prototype 之类的库从未完全满意的原因)。

  • 这有几个原因,但主要原因是我不想担心我的库/模块的加载顺序,而不是简单地管理依赖项。独立的模块根本不应该相互影响。当您在加载时操作模块中的 DOM 时,迟早您会意识到另一段代码期望 DOM 在某个时间处于某个状态,您现在必须关心您是否在该时间之前或之后加载您的模块。这是一个额外的复杂性,它基本上隐藏在加载模块的脚本标签中。

  • 这里的另一个问题是可移植性和适应性。也许你会想在另一个项目中使用你的模块和另一个 DOM 设置。也许您希望将不同的 DOM 元素或配置变量传递init()给特定页面上的函数。如果您init()自动执行,您将失去配置的机会。

所以我一般做的就是将init()方法设置为返回模块对象的一个​​属性:

var foo = (function() {

    function init() {
        // Do something crazy that's gonna be the same across all my web pages
    }

    //...

    return {
        init: init,
        // etc
    }
}());

然后在我的代码的其他地方根据需要调用它:

foo.init();

Yes, this adds an extra line of redundant code to the initialization for all my pages (though this is probably just one other script anyway, so the added weight is all of 11 characters). But it allows me a more fine-grained control over when the module is initialized, and offers a hook for configuration arguments when I (inevitably) determine I need them later.

于 2011-10-04T19:03:31.167 回答
1

init()跨网页的功能是否相同?如果是这样,这就是我要做的:

var foo = (function()
{
    init();
    return {};
}());

如果没有,我看不出使用 IIFE 的理由,并且会像这样简化您的原始代码:

var foo = (function()
{
    /* body of the original IIFE here */
    return {};
}());
于 2011-10-04T17:45:56.860 回答