2012-02-21 65 views
1

这两个JavaScript模式非常相似。我想知道哪一个更好,为什么以及如何改进。这两种JavaScript模式之间的优点和缺点是什么?

第一种方法:

"MODULE" in window || (window.MODULE = {}); 

MODULE.utils = (function ($) { 

    var utils = {}; 

    //public 
    utils.todo = function() { 
     //# 
    } 

    //private 
    function init() { 
     //# 
    } 

    init(); 

    return utils; 
}(jQuery)); 

第二种方法

"MODULE" in window || (window.MODULE = {}); 

MODULE.utils = (function() { 

    function todo(){ 
     //# 
    } 

    function init() { 
     //# 
    } 

    return { 
     init:init 
    } 

})(); 


$(function() { 
    MODULE.utils.init(); 
}); 

回答

4

你的两个选择并没有太多的优点或缺点,更多的是关于个人偏好。两者都可以调整,以提供更好的范围。

我有我自己的偏好,它依靠Underscore。它并没有真正促进私有变量或函数,但我很少发现这是一个问题。如果你想介绍jQuery等,最好用一个匿名函数包装为$实际上是jQuery(或可互换的图书馆)。如你在下面看到的,我的首选项需要更多的代码才能让你走(尽管有些不是必需的),但是试过了你最初提出的一些变体,我发现我的解决方案使其更易于理解代码,其他开发人员更容易掌握正在发生的事情,特别是如果他们具有Backbone.View的经验。

编辑:包装在一个匿名函数来演示集成jQuery和受保护的范围。

var MyNamespace = MyNamespace || {}; 

(function($, MyNamespace) { 

    MyNamespace.MyModule = function(options) { 
     this.defaults = this.defaults || {}; 
     // have had trouble with _.defaults so _.extend instead 
     this.options = _.extend({}, this.defaults, options); 
     this.initialize.call(this); 
     // define private stuff in here if you want 
    }; 

    _.extend(MyNamespace.MyModule.prototype, { 

     defaults: { 
      myOption: "test" 
     }, 

     initialize: function() 
     { 
      // ensure this always refers to our MyModule instance 
      _.bindAll(this); 
      this.$el = $("#some-widget"); 
      // Look Ma! log is already binded to this! 
      this.$el.on("click", this.log); 
     }, 

     setMyOption: function(value) 
     { 
      this.options.myOption = value; 
     }, 

     log: function() 
     { 
      console.log("myOption: ", this.options.myOption); 
     } 

    }); 

})(jQuery, MyNamespace) 

var myModule = new MyNamespace.MyModule({ myOption: "Hey SO!" }); 
myModule.log(); // -> myOption: Hey SO! 
myModule.setMyOption("Setter"); 
myModule.log(); // -> myOption: Setter 
1

第二种方法假设名为$的变量是接受一个参数,这也是一个功能的功能 - 可能是一个假设$ == jQuery。这可能并非总是如此。在第一种方法中,您保证$ == jQuery在您的模块范围内,因为您将它作为参数传递给初始化模块的匿名函数。

除此之外,两者之间没有太大的区别。我更喜欢暴露公共方法的第二种方法,这样我的语法对于公共方法和私有方法来说都是相同的,所以我必须明确指定哪些方法是公开的。但这只是风格。

2
"MODULE" in window || (window.MODULE = {}); 

为什么这样做?我们已经在全球范围内这里,对,所以我们可以这样做:

var MODULE = MODULE || {}; 

其他的是的是,唯一真正的区别(除了风格以外)是第一个例子init从内马上打电话“模块”,而在第二个示例中,在稍后的某个时间点手动调用init(即使在此情况下模块加载后立即执行)。所以,如果您需要延迟拨打init,第二个是可取的;如果你希望它立即发生,第一个是可取的(除了对风格的偏好)。

相关问题