4

我已经看到了编写自调用函数的下一种方法:

(function (app) {
    app.foo = {
        bar: function(){}
    };
}(App));

App全局对象在哪里。

我想知道,为什么我们需要将App参数作为参数传递给函数?为什么不直接使用这个:

(function () {
    App.foo = {
        bar: function(){}
    };
}());

我只看到使用第一种方式的一个优势。如果我们出于某种原因重命名App对象,那么我们可以轻松地重命名括号中的参数,我们的代码将正常工作。但是在第二种方式的情况下,我们可能需要App在我们使用它的所有地方重命名。

还有其他区别吗?

4

4 回答 4

9

这意味着函数的内容——关于app标识符——与全局(或父)范围无关。

这样做的一种情况是,例如,使用 jQuery,当您不想假设调用 jQuery 对象时$(例如,如果打开无冲突模式),但您确实想通过以下方式调用它那个名字。通过这样的匿名函数(即(function($) {})(jQuery))传递它允许您生成一个本地范围的别名,该别名不会干扰$父/全局范围内名称的外部含义。

于 2013-01-18T13:49:36.467 回答
2

其他答案解释了拥有本地范围副本的好处。还有其他一些好处:

  • 作为一种微优化,它减少了范围查找(查找本地变量比查找全局变量更便宜)。
  • 它可以帮助缩小过程,因为您的所有参数都简化为名为 vars 的单个字母。
  • 它为您提供了一种伪依赖管理技术......在您的示例中,您知道您的代码依赖于App.
于 2013-01-18T14:14:00.560 回答
1

例如,许多库使用“$”字符作为其主要功能(例如 JQuery)的快捷方式。这很方便,但在使用多个库时可能会导致冲突。所以,你可以这样传入JQuery

(function($) {
    // Code
    var nav = $('#nav');
    // More code
})(JQuery);

这样,您仍然可以使用方便的快捷方式,但也可以避免冲突(只要您还将库配置为不使用“$”快捷方式)。

于 2013-01-18T13:53:06.513 回答
1

您还可以使用它在本地重新定义全局变量,以确保它们包含您期望的内容:

(function($, undefined) { ... })(jQuery);

undefined现在预期的未定义在哪里。另请参阅:传入未定义的目的是什么?

其他答案中很好地涵盖了大多数其他用途。

于 2013-03-21T10:23:00.397 回答