简体   繁体   English

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

[英]What's the difference between these two JavaScript patterns

I am trying to organize my JavaScript better. 我想更好地组织我的JavaScript。 My goal is to have modular architecture that I can break into separate files (sitename.js, sitename.utils.js etc). 我的目标是拥有模块化架构,我可以分成不同的文件(sitename.js,sitename.utils.js等)。

I'd like to know what are advantages and disadvantages of these two patterns and which one is more suitable for breaking into modules that live in separate files. 我想知道这两种模式的优点和缺点是什么,哪一种更适合分解生活在单独文件中的模块。

PATTERN #1 (module 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 (singleton) 模式#2(单身人士)

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

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

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

Personally, I recommend an extension of #1, as follows: 就个人而言,我建议扩展#1,如下所示:

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

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

  // ...

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

I like this pattern for a couple reasons. 我喜欢这种模式有几个原因。 One, documentation (specifically javadoc-style) look more natural when all your functions are declarations rather than a big hash. 一,当所有函数都是声明而不是大哈希时,文档(特别是javadoc样式)看起来更自然。 Two, if your submodules grow in size, it lets you break them into multiple files without any refactoring. 第二,如果您的子模块的大小增加,它可以让您将它们分成多个文件而不进行任何重构。

For example, if Module.Users were to go into its own file: 例如,如果Module.Users要进入它自己的文件:

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

  // ...

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

Now "module.js" and "module.users.js" can be separate files, and they'll work regardless of the order they are loaded. 现在“module.js”和“module.users.js”可以是单独的文件,无论加载的顺序如何,它们都可以工作。 Also note the local scoping of the module name - this is very handy if your module name is long, because you can take "MyApp.Users.EditScreen" and refer to it with a variable like "ES" within the scope of your module definition. 另请注意模块名称的本地范围 - 如果您的模块名称很长,这非常方便,因为您可以使用“MyApp.Users.EditScreen”并在模块定义范围内使用类似“ES”的变量引用它。

The first pattern allows for private variables, methods, etc via closures. 第一种模式允许通过闭包的私有变量,方法等。 For example: 例如:

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");
            }
        }
    }
})();

privateStuff and doStuff are not properties of the object, and are not available to anything but what's defined inside the function that returns MODULE . privateStuffdoStuff不是对象的属性,除了在返回MODULE的函数内定义的内容之外,它们不可用。 So showing an example for how to do this with #2 is not possible. 因此,展示如何使用#2执行此操作的示例是不可能的。

JS doesn't have the concept of private members, so you can't define them via a regular object literal. JS没有私有成员的概念,因此您无法通过常规对象文字定义它们。 So if you need private stuff, go for the first option. 因此,如果您需要私人物品,请选择第一个选项。 If you don't, though, #2 is simpler. 但是,如果不这样做,#2就更简单了。

Your code as written is pretty much the same. 您编写的代码几乎相同。 However, the first form is much easier to work with as you evolve your code, because it allows you to add private variables and functions. 但是,随着代码的发展,第一种形式更容易使用,因为它允许您添加私有变量和函数。 The second form doesn't support this, and you nearly always end up wanting the first form eventually. 第二种形式不支持这一点,你几乎总是最终想要第一种形式。

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

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