Шаблон модуля JavaScript - Как насчет использования «вернуть это»? - PullRequest
14 голосов
/ 26 апреля 2010

После прочтения шаблона модуля я увидел несколько способов вернуть свойства, которые вы хотите сделать общедоступными.

Одним из наиболее распространенных способов является объявление ваших общедоступных свойств и методов прямо внутри оператора return, кроме ваших личных свойств и методов. Аналогичный способ (шаблон «выявление») - просто предоставить ссылки на свойства и методы, которые вы хотите сделать общедоступными. Наконец, третий метод, который я видел, заключался в создании нового объекта внутри функции вашего модуля, которому вы назначаете свои новые свойства перед возвратом указанного объекта. Это была интересная идея, но требует создания нового объекта.

Итак, я подумал, почему бы просто не использовать this.propertyName для назначения ваших общедоступных свойств и методов и, наконец, использовать return this в конце? Этот способ кажется мне намного проще, поскольку вы можете создавать частные свойства и методы с обычным синтаксисом var или function или использовать синтаксис this.propertyName для объявления ваших открытых методов.

Вот метод, который я предлагаю:

(function() {

var privateMethod = function () {
    alert('This is a private method.');
}

this.publicMethod = function () {
    alert('This is a public method.');
}

return this;

})();

Есть ли плюсы / минусы использования вышеописанного метода? А как насчет других?

Ответы [ 5 ]

30 голосов
/ 26 апреля 2010

Ваша функция не имеет контекста объекта, поэтому this ссылается на глобальный window объект в этом случае. Каждое свойство, которое вы назначаете this, автоматически загрязняет глобальное пространство имен.

(function() {
    console.log(this == window); // true

    this.publicMethod = function () {
        alert('This is a public method.');
    }

})();

console.log(publicMethod); // function()

Вы можете явно передать ему объект, чтобы указать, какой контекст использовать.

var MYAPP = {};

(function() {
    // 'this' will now refer to 'MYAPP'
    this.publicMethod = function () {
        alert('This is a public method.');
    }
}).call(MYAPP);

console.log(publicMethod); // undefined
console.log(MYAPP.publichMethod); // function()

Который вы можете написать в несколько ином стиле:

var MYAPP = (function(my) {
    var my;
    ⋮
    return my;
})(MYAPP);

И мы подошли к уже обсуждаемой схеме . Для получения дополнительной информации см. Статью Дастина о Определение анонимных функций .

4 голосов
/ 26 апреля 2010

Я бы порекомендовал стиль, в котором вы добавляете свои публичные свойства и методы к анонимному объекту, который затем возвращаете:

var myModule = (function() {
    function privateMethod() { ... }
    function publicMethod() { ... }

    return { publicMethod: publicMethod };
})();
2 голосов
/ 26 апреля 2010

Другой вариант - вообще не использовать ссылку this . Определите функцию, которая вместо этого создает и возвращает анонимный объект.

function makeThing(someAttribute) {
  var privateVariable = 42;

  function someMethod() {
    return privateVariable;
  }

  return {
    "publicMethodName": someMethod,
    "getAttribute": function() {
      return someAttribute;
    }
  };
}

var thing = makeThing(99);
thing.publicMethodName();
thing.getAttribute();
2 голосов
/ 26 апреля 2010

если вы хотите опубликовать методы, то сделайте что-то вроде:

var export = (function() {

var privateMethod = function () {
  alert('This is a private method.');
}
var export = {};

export.publicMethod = function () {
  alert('This is a public method.');
}

return export;

})();
1 голос
/ 20 сентября 2013

Выявление шаблонов модулей:

var m1 = (function(){ return {method: mthod} })();
var m2 = new function Singleton(){ return {method: mthod} };
var m3 = ({}).prototype = {method: method};
var m4 = ({}).prototype = (function(){ ... })();
var m5 = (function(){}).prototype = {} || (function(){ ... })();

var m6 = (function(extendee){
    return extendee.prototype = {attr3: 'attr3'};
})({currentAttr1: 1, currentAttr2: 2});

Также, если вам нужен метод цепочки:

var m = (function(){}).prototype = (function(){
    var thus = m;  // this
    console.log('m this-------', thus);

    function fn(){
        console.log('fn', thus);
        return thus;
    }
    function f(){
        console.log('f', thus);
        return 'poop';
    }

    return {f: f, fn: fn};
})();

console.log('M:', m, 'm.fn', m.fn(), 'm.fn.f', m.fn().f());

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

...