Comments 32
Давно хотелось почитать нечто подобное.
наконец то я понял назначение замыканий в js :) спасибо за перевод и ссылку!
Далеко не все можно описать этими анонимными замыканиями. Не везде они удобны.
Мне кажется, что проще так:
var MODULE = (function (my) {
my.anotherMethod = function () {
// added method...
};
return my;
}(MODULE));
Мне кажется, что проще так:
var MODULE = (function (my) {
this.anotherMethod = function () {
// added method...
};
return my;
}).call(MODULE);
В чем преимущества вашей альтернативы?
Вы хотели написать:
var MODULE = (function () {
this.anotherMethod = function () {
// added method…
};
return this;
}).call(MODULE);
?
var MODULE = (function () {
this.anotherMethod = function () {
// added method…
};
return this;
}).call(MODULE);
?
var MODULE = new function () {
this.anotherMethod = function () {
// added method...
};
return this;
};
Конечно, так модуль нельзя будет расширять где-то в другом месте, но мне такой подход вообще не нравится. Есть ведь отличный подход с прототипами, который намного ближе к идеологии JS
Хотя можно даже так:
var MODULE = new function () {
this.anotherMethod = function () {
// added method...
};
};
А я и не говорил, что я в восторге. Но так иногда делают, и я иногда так делаю, когда это кажется уместным.
Я всего лишь сделал более явным тот факт, что происходит расширение объекта.
Да и вообще — будь это готовый фреймворк, было бы клево, а так — просто подход.
Кроме того, если уж автор оригинала использует jQuery, то есть, имхо, более удачные способы инкапсуляции.
Я всего лишь сделал более явным тот факт, что происходит расширение объекта.
Да и вообще — будь это готовый фреймворк, было бы клево, а так — просто подход.
Кроме того, если уж автор оригинала использует jQuery, то есть, имхо, более удачные способы инкапсуляции.
Самое хитрое в модульном подходе это моменты модульной сборки и возможности в модуле определять различные классы работающие именно в пространстве данного модуля( что тянет за собой различные implements\provide\register\require и другие exports).
А описание переменой в локальном замыкании — это разве модульность?
А описание переменой в локальном замыкании — это разве модульность?
Вообще YUI3 занятная штука, крайне рекомендую
Я больше предпочитаю «активный» экспорт. Потому, что он больше вяжется с CommonJS Modules и отлично подходит как для Node.js так и для браузера.
Если использовать такой вид модуля, не экспортировать в глобалы и написать хороший сборщик (1 .js файл), то мы можем избавить window от лишних глобальных объектов, что является самой сложной техникой JavaScript Ninja ;)
(function (exports/* остальные объекты и алиасы по вкусу */) {
var MyObject = {};
exports.MyObject = MyObject;
}(typeof exports === 'undefined' ? window : exports));
// Если надо расширить, то
(function (MyObject) {
MyObject.smth = function () {};
}(typeof require === 'undefined' ? MyObject : require('MyObject'));
Если использовать такой вид модуля, не экспортировать в глобалы и написать хороший сборщик (1 .js файл), то мы можем избавить window от лишних глобальных объектов, что является самой сложной техникой JavaScript Ninja ;)
Мне нравится ваше кунг-фу:)
может отдельную статью запостишь по этому поводу?
возможно не до конца понял, но видимо это самый верный путь.
поделишься подходом в развёрнутом виде??
возможно не до конца понял, но видимо это самый верный путь.
поделишься подходом в развёрнутом виде??
CommonJS modules это вещь. Если хотите поэксперементировать с ними, советую попробовать прямо из браузера на Akshelle
ага, вещь. из-за их баловства с эвалом фиг найдёшь место ошибки.
а в акшелле нет банальной консоли ошибок, из-за чего полезность всех их свистелок стремится к нулю.
а в акшелле нет банальной консоли ошибок, из-за чего полезность всех их свистелок стремится к нулю.
С каким эвалом? Он вообще здесь ни причем.
А в акшеле stack trace видно в HTML в Preview и в Eval консоле тоже. Добавь строку 'throw new Error();' и убедись сам(а).
А в акшеле stack trace видно в HTML в Preview и в Eval консоле тоже. Добавь строку 'throw new Error();' и убедись сам(а).
docs.google.com/present/view?hl=en&id=dcd8d5dk_0cs639jg8 9 слайд
днём не выводил. хотя, может я писал просто throw 123, не помню уже.
днём не выводил. хотя, может я писал просто throw 123, не помню уже.
Никогда не понимал, зачем тащить всякие private/protected из языков вроде Java в динамические языки вроде JavaScript или Perl. Да, с помощью клозур и такой-то матери можно что-то спрятать, но нафига это нужно?! Если кто-то захочет залезть внутрь и отстреляться себе по ногам — всё-равно залезет и отстреляется, так или иначе. А потом начинают изобретать извращения чтобы добраться к тому, к чему сами себе закрыли доступ.
Практика показывает, что для разделения на public и private более чем достаточно соглашения об именах: private методы и свойства начинаются на подчёркивание. Этого более чем достаточно, чтобы сохранить наглядность интерфейса, и чтобы легко обнаруживать нарушения инкапсуляции во время code review (а то и автоматически, просто запустив grep по исходникам).
Практика показывает, что для разделения на public и private более чем достаточно соглашения об именах: private методы и свойства начинаются на подчёркивание. Этого более чем достаточно, чтобы сохранить наглядность интерфейса, и чтобы легко обнаруживать нарушения инкапсуляции во время code review (а то и автоматически, просто запустив grep по исходникам).
Статья повествует о том, как вынести детали реализации из глобальной области видимости по модулям.
Вы же не отрицаете тот факт, что разные программисты в разных частях одной программы могут случайно использовать одинаковые глобальные идентификаторы, что может привести к достаточно противным ошибкам?
Вы же не отрицаете тот факт, что разные программисты в разных частях одной программы могут случайно использовать одинаковые глобальные идентификаторы, что может привести к достаточно противным ошибкам?
Не отрицаю. Но я об этом ничего и не говорил. Просто я для реализации модулей предпочитаю более нативный подход через prototype, а не клозуры:
На мой взгляд это значительно проще и читабельнее, чем вариант на клозурах.
var MODULE = function(){ this.public = 'some'; this._private = 'some'; }; MODULE.prototype.public_method = function(){ this._private_method(); }; MODULE.prototype._private_method = function(){ … }; obj = new MODULE();
На мой взгляд это значительно проще и читабельнее, чем вариант на клозурах.
приватные поля предназначены для того, чтобы можно было объявлять их в родителе не боясь, что потомок их _случайно_ испоганит решив воспользоваться тем же именем. никакие подчёркивания тут не помогут.
Я стараюсь не злоупотреблять наследованием. Даже, я бы сказал, не употреблять вообще. :) Это сильно упрощает жизнь.
А в тех редких случаях, когда наследование действительно удобно — как правило либо классы родителя и потомков пишутся одним разработчиком, контролирующим такие конфликты, либо в потомке для гарантии отсутствия конфликтов его личные приватные свойства и методы содержат префикс — имя потомка. Да, удобным и элегантным подходом это никак не назовёшь, и при активном использовании наследования описанные в статье подходы будут предпочтительнее. Но если наследование используется в качестве исключения, а не правила, то этих простых подходов более чем достаточно.
А в тех редких случаях, когда наследование действительно удобно — как правило либо классы родителя и потомков пишутся одним разработчиком, контролирующим такие конфликты, либо в потомке для гарантии отсутствия конфликтов его личные приватные свойства и методы содержат префикс — имя потомка. Да, удобным и элегантным подходом это никак не назовёшь, и при активном использовании наследования описанные в статье подходы будут предпочтительнее. Но если наследование используется в качестве исключения, а не правила, то этих простых подходов более чем достаточно.
Спасибо за статью, давно хотел разобраться как проще всего организовать модули на JavaScript без внешних библиотек.
Sign up to leave a comment.
Модульный подход в JavaScript