В чем разница между этими двумя шаблонами JavaScript - PullRequest
9 голосов
/ 02 октября 2011

Я пытаюсь лучше организовать свой 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");
            }
        }
    }
})();

ШАБЛОН № 2 (синглтон)

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

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

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

Ответы [ 3 ]

8 голосов
/ 02 октября 2011

Лично я рекомендую расширение # 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» в рамках определения вашего модуля. .

2 голосов
/ 02 октября 2011

Первый шаблон допускает закрытые переменные, методы и т. Д.Например:

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 и doStuff не являются свойствами объекта и не доступны ни для чего, кроме того, что определено внутри функции, которая возвращает MODULE.Так что показать пример того, как это сделать с # 2, невозможно.

В JS нет концепции закрытых членов, поэтому вы не можете определить их с помощью обычного литерала объекта.Так что, если вам нужны личные вещи, выберите первый вариант.Если нет, то №2 проще.

1 голос
/ 02 октября 2011

Ваш код, как написано, почти такой же. Тем не менее, с первой формой гораздо проще работать по мере развития вашего кода, поскольку она позволяет добавлять частные переменные и функции. Вторая форма не поддерживает это, и вы почти всегда в конечном итоге хотите получить первую форму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...