Pull to refresh

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);

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

Ну и правильнее как-то создавать отдельный контекст (ну или использовать существующий) — потому что в исходном варианте this — это window (точнее, глобальный объект).
Вы хотели написать:

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...
    };
};
var MODULE = new function () {
Object( MODULE ).constructor.apply( this )
this.anotherMethod = function () {
// added method…
};
};
UFO landed and left these words here
А я и не говорил, что я в восторге. Но так иногда делают, и я иногда так делаю, когда это кажется уместным.
Я всего лишь сделал более явным тот факт, что происходит расширение объекта.

Да и вообще — будь это готовый фреймворк, было бы клево, а так — просто подход.

Кроме того, если уж автор оригинала использует jQuery, то есть, имхо, более удачные способы инкапсуляции.
Я не делаю вам замечание. Просто дополнил)
UFO landed and left these words here
UFO landed and left these words here
Самое хитрое в модульном подходе это моменты модульной сборки и возможности в модуле определять различные классы работающие именно в пространстве данного модуля( что тянет за собой различные implements\provide\register\require и другие exports).
А описание переменой в локальном замыкании — это разве модульность?
Я больше предпочитаю «активный» экспорт. Потому, что он больше вяжется с CommonJS Modules и отлично подходит как для Node.js так и для браузера.
(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();' и убедись сам(а).
Ну это только в их имплементации, вообще-то эвал в других местах не используется для этого.
Никогда не понимал, зачем тащить всякие private/protected из языков вроде Java в динамические языки вроде JavaScript или Perl. Да, с помощью клозур и такой-то матери можно что-то спрятать, но нафига это нужно?! Если кто-то захочет залезть внутрь и отстреляться себе по ногам — всё-равно залезет и отстреляется, так или иначе. А потом начинают изобретать извращения чтобы добраться к тому, к чему сами себе закрыли доступ.

Практика показывает, что для разделения на 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 без внешних библиотек.
Only those users with full accounts are able to leave comments. Log in, please.