Разница между раскрывающимся шаблоном модуля и простым конструктором

Погуглил, но не нашел подходящего ресурса, объясняющего разницу между использованием шаблона раскрывающегося модуля и ключевым словом this.

При использовании раскрывающегося шаблона модуля у меня может быть следующий код:

var moduleRevealing = function() {
    var talk = function() {
      console.log("Talking....");
    };
    var walk = function() {
      console.log("Walking...");
    };
    return {
      talk: talk,
      walk: walk
    }
  };

  console.log('Module Pattern Object');
  console.log(moduleRevealing());

Теперь того же можно добиться с помощью ключевого слова this, как показано ниже:

var module = function() {
    var talk = function() {
      console.log("Talking....");
    };
    this.walk = function() {
      console.log("Walking...");
    };
    this.talk = talk;
  };
  var mod1 = new module();
  console.log('Module Object');
  console.log(mod1);

Чем оба отличаются? Я вижу только одну разницу, и это __proto; Первый указывает на Object, а второй — на module.

Если кто-то хочет увидеть код - Fiddle


person Shubh    schedule 23.02.2016    source источник
comment
Эта функция moduleRevealing не должна вызываться с new. Где вы такое нашли?   -  person Bergi    schedule 23.02.2016
comment
@Bergi Спасибо, что указали на это. Моя ошибка, исправил. Это не имело смысла, когда я возвращаю объект.   -  person Shubh    schedule 23.02.2016
comment
Кстати, да, именно наследование прототипов и есть вся разница между фабричной функцией и конструктором. Если свойств для наследования нет, следует использовать фабрику.   -  person Bergi    schedule 23.02.2016


Ответы (2)


В вашем простом примере нет никакой разницы, но позвольте мне немного усложнить его.

var moduleRevealing = function() {
    var talk = function() {
      console.log("Talking....");
    };
    var walk = function() {
      console.log("Walking...");
    };
    var walkAndTalk = function(){
      walk();
      talk();
    };
    return {
      talk: talk,
      walk: walk,
      walkAndTalk: walkAndTalk
    }
  };

Используя this,

var module = function() {
    var talk = function() {
      console.log("Talking....");
    };
    this.walk = function() {
      console.log("Walking...");
    };
    this.talk = talk;
    this.walkAndTalk = function(){
      this.walk();
      this.talk();
    }
  };

Эти два немного более сложных примера теперь ведут себя по-разному, когда вы переопределяете их методы.

var modR = moduleRevealing();
var mod1 = new module();
modR.walk = function() {console.log('FAST Walking...");}
mod1.walk = function() {console.log('FAST Walking...");}

modR.walk(); // outputs "FAST Walking..."
modl.walk(); // outputs "FAST Walking..."

modR.walkAndTalk(); // outputs "Walking ... Talking..."
mod1.walkAndTalk(); // outputs "FAST Walking...Talking..."

Обратите внимание, что несмотря на то, что выходные данные walk() изменились, когда вы переопределяете экземпляр, созданный с помощью Revealing Module, это изменение не подхватывается зависимым методом walkAndTalk(). Основная причина заключается в том, что паттерн Revealing Module поощряет неразборчивое использование замыканий JavaScript для людей, которые не удосужились изучить this должным образом. См. этот мой пост для сравнения различий между вариантами шаблона модуля.

person I-Lin Kuo    schedule 23.02.2016

В вашем примере фактически нет разницы (за исключением тонкостей constructor и т. д.). Оба возвращают объект с новой копией каждого прикрепленного метода. Если бы talk и walk были частью module.prototype, все было бы иначе.

person Mathletics    schedule 23.02.2016