这两个JavaScript模式有什么区别呢?

时间:2022-06-21 15:49:17

I am trying to organize my JavaScript better. My goal is to have modular architecture that I can break into separate files (sitename.js, sitename.utils.js etc).

我正试图更好地组织我的JavaScript。我的目标是拥有模块化的体系结构,我可以将其分解为单独的文件(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");
    }
  }
};

3 个解决方案

#1


8  

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. Two, if your submodules grow in size, it lets you break them into multiple files without any refactoring.

我喜欢这种模式有几个原因。首先,当所有函数都是声明而不是大散列时,文档(特别是javadocstyle)看起来更自然。第二,如果您的子模块在大小上增长,它允许您在不进行任何重构的情况下将它们分解成多个文件。

For example, if Module.Users were to go into its own file:

例如,如果模块。用户将进入自己的文件:

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. 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.

现在“模块。js”和“module.users。js“可以是单独的文件,不管它们的顺序如何,它们都可以工作。”还要注意模块名称的局部范围——如果您的模块名称很长,这非常方便,因为您可以使用“MyApp.Users”。EditScreen,并在模块定义的范围内使用“ES”这样的变量引用它。

#2


2  

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. So showing an example for how to do this with #2 is not possible.

privateStuff和doStuff并不是该对象的属性,除了在返回模块的函数中定义的内容之外,其他任何东西都不能使用。因此,展示一个如何使用#2的例子是不可能的。

JS doesn't have the concept of private members, so you can't define them via a regular object literal. So if you need private stuff, go for the first option. If you don't, though, #2 is simpler.

JS没有私有成员的概念,所以您不能通过普通的对象文字来定义它们。所以如果你需要私人物品,那就选择第一个。但如果你不这样做,#2就更简单了。

#3


1  

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.

你写的代码基本上是一样的。但是,随着代码的发展,第一个表单要容易得多,因为它允许您添加私有变量和函数。第二种形式不支持这一点,你最终几乎总是想要第一个表单。

#1


8  

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. Two, if your submodules grow in size, it lets you break them into multiple files without any refactoring.

我喜欢这种模式有几个原因。首先,当所有函数都是声明而不是大散列时,文档(特别是javadocstyle)看起来更自然。第二,如果您的子模块在大小上增长,它允许您在不进行任何重构的情况下将它们分解成多个文件。

For example, if Module.Users were to go into its own file:

例如,如果模块。用户将进入自己的文件:

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. 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.

现在“模块。js”和“module.users。js“可以是单独的文件,不管它们的顺序如何,它们都可以工作。”还要注意模块名称的局部范围——如果您的模块名称很长,这非常方便,因为您可以使用“MyApp.Users”。EditScreen,并在模块定义的范围内使用“ES”这样的变量引用它。

#2


2  

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. So showing an example for how to do this with #2 is not possible.

privateStuff和doStuff并不是该对象的属性,除了在返回模块的函数中定义的内容之外,其他任何东西都不能使用。因此,展示一个如何使用#2的例子是不可能的。

JS doesn't have the concept of private members, so you can't define them via a regular object literal. So if you need private stuff, go for the first option. If you don't, though, #2 is simpler.

JS没有私有成员的概念,所以您不能通过普通的对象文字来定义它们。所以如果你需要私人物品,那就选择第一个。但如果你不这样做,#2就更简单了。

#3


1  

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.

你写的代码基本上是一样的。但是,随着代码的发展,第一个表单要容易得多,因为它允许您添加私有变量和函数。第二种形式不支持这一点,你最终几乎总是想要第一个表单。