- PVSM.RU - https://www.pvsm.ru -
У меня сложилось впечатление, что в обществе все же есть предубеждение против использования глобальных переменных в служебных целях. В связи с этим, хочу дать некоторые разъяснения с примерами, которые снимут всякие сомнения и будут полезны всем, кто жаждет модульности и гибкости в JavaScript разработке. Я не могу проследить источники всех идей, приведенных ниже, но я не претендую на их авторство, а лишь на творческое обобщение. Так же я отказываюсь от претензий на один универсальных паттерн определения модйлей для всех случаев жизни, надеюсь, всем ясно, что такого не может быть никогда. Все это существенно отличается от подходов RequireJS, CommonJS и того, как модули оформляются в node.js через module.exports, однако, каждый из этих паттернов имеет свое место, если подходить к задаче без фанатизма и предубеждений.
// File: global.js
// Должен быть загружен первым
if (typeof(window) != 'undefined') window.global = window;
Function.prototype.override = function(fn) {
var superFunction = this;
return function() {
this.inherited = superFunction;
return fn.apply(this, arguments);
}
}
// File: moduleName.js
// первое определение модуля moduleName (например, для реализации абстрактного интерфейса)
(function(moduleName) {
// Помещайте инициализационный код тут
console.log('Инициализация moduleName');
moduleName.publicProperty = 'Значение публичного свойства';
var privateProperty = 'Значение приватного свойства';
moduleName.publicMethod = function() {
console.log('Исходный publicMethod для moduleName');
};
moduleName.toBeOverridden = function() {
console.log('Исходный публичный метод toBeOverriden для модуля moduleName (будет переопределен)');
};
privateMethod = function() {
console.log('Приватный метод privateMethod для moduleName');
};
} (global.moduleName = global.moduleName || {}));
// File: moduleName.implementationName.js
// повторное определение модуля moduleName может расширять, переопределять и вызывать унаследованную функциональность
(function(moduleName) {
// Помещайте инициализационный код для повторного оперделения тут
console.log('Инициализация implementationName');
// Публичное свойство в повторном определении
// будет перекрывать публичное свойство первого определения
//
moduleName.publicProperty = 'Публичное свойство перекрыто';
// Приватное свойство в повторном определении
// не будет перекрывать приватное свойство первого определения
//
var privateProperty = 'Приватное свойство не перекрыто';
moduleName.publicMethod = function() {
// Публичное свойство в повторном определении
// будет перекрывать публичное свойство первого определения
console.log('Публичный метод перекрыт');
};
privateMethod = function() {
console.log('Приватный метод не перекрыт');
};
// Переопределение метода через "Function.override"
//
moduleName.toBeOverridden = moduleName.toBeOverridden.override(function() {
console.log('Переопределенный метод: moduleName.toBeOverridden');
this.inherited(); // вызов предыдущей реализации метода
});
// Обертка части переопределения, которая будет инициализироваться опционально
// по какому-либо условию из внешнего кода или из блока инициализации
//
moduleName.wrapperName = function() {
// Помещайте инициализационный код обертки тут
console.log('Обертка инициализирует скрутый функционал');
moduleName.publicMethod = moduleName.publicMethod.override(function() {
console.log('Метод переопределен: moduleName.publicMethod');
});
};
} (global.moduleName = global.moduleName || {}));
// File: test.js
require('./global.js');
require('./moduleName.js');
require('./moduleName.implementationName.js');
moduleName.wrapperName();
moduleName.publicMethod();
1. Вынесение конфигурации: impress.constants.js вынесена из impress.js
2. Подмодули: db.mongodb.js [2] расширяет db.js [3]
3. Так как все обработчики а Impress в отдельных файлах, то в обработчиках не нужно писать require. А вот сами обработчики определяются при помощи обычного для node.js способа, т.е. через module.exports.
Пример:
module.exports = function(req, res, callback) {
res.context.data = [];
db.impress.sessions.find({}).toArray(function(err, nodes) {
res.context.data = nodes;
callback();
});
}
Global.js с комменариями на русском и английском на Github: github.com/tshemsedinov/global.js [4]
Impress на Github: https://github.com/tshemsedinov/impress [5]
Impress в npm: https://npmjs.org/package/impress [6]
Автор: MarcusAurelius
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/36465
Ссылки в тексте:
[1] Impress: http://habrahabr.ru/post/182714/
[2] db.mongodb.js: https://github.com/tshemsedinov/impress/blob/master/lib/db.mongodb.js
[3] db.js: https://github.com/tshemsedinov/impress/blob/master/lib/db.js
[4] github.com/tshemsedinov/global.js: https://github.com/tshemsedinov/global.js
[5] https://github.com/tshemsedinov/impress: https://github.com/tshemsedinov/impress
[6] https://npmjs.org/package/impress: https://npmjs.org/package/impress
[7] Источник: http://habrahabr.ru/post/183188/
Нажмите здесь для печати.