繁体   English   中英

这两种JavaScript模式之间的优缺点是什么?

[英]What are the Advantages and Disadvantages Between These Two JavaScript Patterns?

这两种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();
});

您的两种选择实际上并没有太多利弊,而更多是关于个人喜好。 两者都可以调整以提供更好的范围。

我有自己的偏好,它依赖于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
 "MODULE" in window || (window.MODULE = {} ); 

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

var MODULE = MODULE || {};

其他的是的是,唯一真正的区别(除了款式以外)是在第一个例子中init从内立即被称为“模块”,而你拨打第二个例子init手动在以后的某个时间点(即使它后立即在这种情况下,模块会加载)。 因此,如果需要延迟对init的调用,则最好使用第二个方法; 如果您希望它立即发生,则首选第一个(除了对样式的偏好)。

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

除此之外,两者之间没有太大区别。 我更喜欢使用第二种方法公开公共方法,以便我的语法在公共方法和私有方法中看起来都一样,因此我必须明确指定哪些方法是公共的。 但这只是风格。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM