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 just landed and posted this here
А я и не говорил, что я в восторге. Но так иногда делают, и я иногда так делаю, когда это кажется уместным.
Я всего лишь сделал более явным тот факт, что происходит расширение объекта.

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

Кроме того, если уж автор оригинала использует jQuery, то есть, имхо, более удачные способы инкапсуляции.
Я не делаю вам замечание. Просто дополнил)
UFO just landed and posted this here
UFO just landed and posted this 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 без внешних библиотек.
Sign up to leave a comment.

Articles