Шаблон модуля JavaScript. Как насчет использования "return this"?
После некоторого чтения о шаблоне модуля я видел несколько способов вернуть свойства, которые вы хотите публиковать.
Один из наиболее распространенных способов - объявить свои общедоступные свойства и методы прямо внутри оператора 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;
})();
Есть ли какие-либо плюсы и минусы для использования метода выше? Как насчет других?
Ответы
Ответ 1
У вашей функции нет контекста объекта, поэтому 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);
И мы прибыли в уже обсуждавшийся шаблон. Для получения дополнительной информации см. Статью Дастина о Определение анонимных функций.
Ответ 2
Я бы рекомендовал стиль, в котором вы добавляете свои общедоступные свойства и методы к анонимному объекту, который вы затем возвращаете:
var myModule = (function() {
function privateMethod() { ... }
function publicMethod() { ... }
return { publicMethod: publicMethod };
})();
Ответ 3
если вы хотите опубликовать методы, тогда сделайте что-то вроде:
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;
})();
Ответ 4
Другой вариант - вообще избегать ссылки 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();
Ответ 5
Выявление шаблонов модулей:
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());
Также есть много способов, и вы также можете создавать свои модули.