立即调用函数表达式没有任何私有变量也没有返回值?

时间:2012-09-16 02:07:31

标签: javascript

我正在阅读javascript设计模式书,并在阅读“命令模式”时遇到了下面的代码。我一直试图理解为什么这个代码包含一个立即调用的匿名函数,特别是因为没有其他私有变量可以关闭。这与将CarManager声明为对象文字有何不同?

(function(){

  var CarManager = {

    // request information
    requestInfo: function( model, id ){
      return 'The information for ' + model + ' with ID ' + id + ' is foobar';
    },

    // purchase the car
    buyVehicle: function( model, id ){
      return 'You have successfully purchased Item ' + id + ', a ' + model;
    },

    // arrange a viewing
    arrangeViewing: function( model, id ){
      return 'You have successfully booked a viewing of ' + model + ' ( ' + id + ' ) ';
    }

  };

})();

3 个答案:

答案 0 :(得分:2)

这个例子略显不完整。

目标是能够提供公共界面。 在IIFE内部,您可以将界面所需的所有部分组合在一起。

您不必通过return语句将其传回。

例如,jQuery以相同的方式构建。 而不是返回声明:

var jQuery = (function () { return magic; }());

他们在函数中手动设置window的{​​{1}}(和jQuery)属性,如下所示:

$

此外,实际发生的事情仍然有点不同。 他们将(function () { window["jQuery"] = magic; }()); 对象传递给IIFE的window参数。 那么它不一定是window。 理论上,它可以是您正在扩展的任何先前定义的对象。

window

在构建类似于jQuery的库时,您可以执行类似的操作。 如果您通常命名任何大型库/应用程序(一个好主意),您可以在内部缩短名称,以使生活更轻松。

而不是:

var NAMESPACED_AWESOME_APP_OF_DOOM = {}; NAMESPACED_AWESOME_APP_OF_DOOM.module1 = {};

您可以执行以下操作:

var myApp = {};
(function (window, document) { window["jQuery"] = public_interface; }(myApp, document));
myApp.jQuery("...");

然后您可以在内部完成所有内部设置,一旦设置完成,您就可以在全局范围内按名称引用应用程序。

在其他情况下,您可以使用这种方式使用闭包为代码创建沙箱,并使用调解器在组件之间来回发送消息。 尼古拉斯·扎卡斯(Nicholas Zakas)对此进行了几次很好的讨论。

最后,有时你只是想完成一些工作,这与你的程序的其余部分100%无关,但仍然需要完成,所有相同(比如进行兼容性检查并将结果绑定到DOM元素,现代化......或者设置只需要存在的cookie,或者启动对分析软件的调用......等等。

答案 1 :(得分:0)

在此特定实例中,匿名函数仅用于防止CarManager在其他地方访问,即进入全局范围。

此特定于此代码实例,它完全没有意义。任何其他代码都无法使用CarManager。

查看评论中提供的链接http://addyosmani.com/resources/essentialjsdesignpatterns/book/#commandpatternjavascript

据我所知,除了CarManager.execute位之外,记录的整个代码部分将完全无法工作。尝试在匿名函数之外定义CarManager.execute = ...将失败,因为CarManager不存在。

答案 2 :(得分:0)

我是OP。基于上面的讨论,在试图解释作者想要表达的内容之后,我得出结论,以下代码可能是作者想要表达的内容。至少对我来说这似乎是有道理的。

(function(){
    var CarManager = {
        requestInfo: function(model, id){
            /* blah blah */
        },
        buyVehicle: function(model, id){
            /* blah blah */
        },
        arrangeViewing: function( model, id ){
            /* blah blah */
        }
    };

    CarManager.execute = function(name){
        return CarManager[name] && CarManager[name].apply(CarManager, Array.prototype.slice(arguments, 1));
    }

    return CarManager;
}());

基本上,我添加了匿名函数执行返回CarManager对象文字的部分。另外,我在返回之前放置了execute方法(虽然我不太明白为什么它应该在原始CarManager对象之外,除了潜在的代码可读性之外)你怎么看?

(顺便说一下,本书部分的网页版本在这里:http://addyosmani.com/resources/essentialjsdesignpatterns/book/#commandpatternjavascript