这两种JavaScript模式之间有什么区别

时间:2011-10-02 04:54:55

标签: javascript design-patterns

我正在尝试更好地组织我的JavaScript。我的目标是拥有模块化架构,我可以分成不同的文件(sitename.js,sitename.utils.js等)。

我想知道这两种模式的优点和缺点是什么,哪一种更适合分解生活在不同文件中的模块。

PATTERN#1(模块模式)

var MODULE = (function () {

    //private methods

    return {
        common: {
            init: function() {
                console.log("common.init");
            }
        },
        users: {
            init: function () {
                console.log("users.init");
            },
            show: function () {
                 console.log("users.show");
            }
        }
    }
})();

PATTERN#2(单身)

var MODULE = {
  common: {
    init: function() {
        console.log("common.init");
    }
  },

  users: {
    init: function() {
      console.log("users.init");
    },

    show: function() {
      console.log("users.show");
    }
  }
};

3 个答案:

答案 0 :(得分:8)

就个人而言,我建议扩展#1,如下所示:

var Module = (function(Module) {
  // A comment
  Module.variable1 = 3;

  /**
   * init()
   */
  Module.init = function() {
    console.log("init");
  };

  // ...

  return Module;
})(Module || {});

我喜欢这种模式有几个原因。一,当所有函数都是声明而不是大哈希时,文档(特别是javadoc样式)看起来更自然。第二,如果子模块的大小增加,它可以让你将它们分成多个文件,而不需要任何重构。

例如,如果Module.Users要进入自己的文件:

var Module = Module || {};
Module.Users = (function(Users) {
  /**
   * init()
   */
  Users.init = function() {
    console.log("Module.Users.init");
  };

  // ...

  return Users;
})(Module.Users || {});

现在“module.js”和“module.users.js”可以是单独的文件,无论加载顺序如何,它们都能正常工作。另请注意模块名称的本地范围 - 如果模块名称很长,这非常方便,因为您可以使用“MyApp.Users.EditScreen”并在模块定义范围内使用类似“ES”的变量引用它

答案 1 :(得分:2)

第一种模式允许通过闭包实现私有变量,方法等。例如:

var MODULE = (function () {

    var privateStuff = 'This is private';

    var doStuff = function(obj) {
        console.log('Doing stuff...');
        console.log(privateStuff);
    };

    return {
        common: {
            init: function() {
                console.log("common.init");
                doStuff(this);
            }
        },
        users: {
            init: function () {
                console.log("users.init");
            },
            show: function () {
                 console.log("users.show");
            }
        }
    }
})();

privateStuffdoStuff不是对象的属性,除了在返回MODULE的函数内定义的内容之外,它不可用。因此,无法显示如何使用#2执行此操作的示例。

JS没有私有成员的概念,因此您无法通过常规对象文字来定义它们。因此,如果您需要私人物品,请选择第一个选项。但是,如果不这样做,#2就更简单了。

答案 2 :(得分:1)

您编写的代码几乎相同。但是,随着代码的发展,第一种形式更容易使用,因为它允许您添加私有变量和函数。第二种形式不支持这一点,你几乎总是最终想要第一种形式。