Шаблон модуля против экземпляра анонимного конструктора - PullRequest
25 голосов
/ 08 октября 2009

Итак, есть так называемый шаблон модуля для создания синглетонов с закрытыми членами:

var foo = (function () {
    var _foo = 'private!';
    return {
        foo: function () { console.log(_foo); },
        bar: 'public!'
    }
})();

Есть также этот метод, который я нашел самостоятельно, но не видел ничего написанного о:

var foo = new function () {
    var _foo = 'private!';
    this.bar = 'public!';
    this.foo = function () { console.log(_foo); };
}

Я думаю, что должна быть причина, почему никто не пишет об этом, в то время как есть множество статей о шаблоне модуля. Есть ли обратная сторона этого паттерна? Скорость или совместимость браузера возможно?

Ответы [ 4 ]

12 голосов
/ 15 февраля 2010

В этом случае кажется, что вы используете только один экземплярный объект из этого "class" . Поэтому, возможно, стоит взглянуть на то, что думает Дуглас Крокфорд о , поставив new прямо перед function:

Используя new для вызова функции, объект удерживается на бесполезном prototype объекте. Это тратит впустую память без компенсирующего преимущества. Если мы не используем новый, мы не будем хранить потраченный впустую объект-прототип в цепочке. Поэтому вместо этого мы будем вызывать фабричную функцию правильным образом, используя ().

Так, в соответствии с известным Javascript архитектором Yahoo! Вы должны использовать первый метод, и у вас есть свои причины там.

3 голосов
/ 08 октября 2009

Более или менее они дают одинаковый результат. Это просто вопрос, по какому пути вы хотите пойти по этому пути.

1-й может быть более популярным, так как это просто смесь из 2 уже распространенных паттернов:

(function closure() {
    var foo = 'private';
    /* ... */
}())

var singleton = {
    bar : 'public'
};

Тем не менее, prototype сцепление будет преимуществом второго шаблона, так как он имеет свой собственный конструктор.

var singleton = new function Singleton() { };
assert(singleton.constructor !== Object);

singleton.constructor.prototype.foo = 'bar';
assert(singleton.foo === 'bar');
1 голос
/ 08 октября 2009

Дуглас Крокфорд пишет о втором. Как говорит Грег в своих комментариях, я подумал, что это довольно часто, и я использовал это в прошлом.

Редактировать: чтобы действительно ответить на ваш вопрос - никаких минусов нет, оба они функционально эквивалентны (оба создают закрытие, содержащее «приватные переменные» и публично открывают другие переменные / методы) и имеют точно такие же характеристики поддержки и производительности браузера , Это просто сводится к вопросу синтаксиса - в основном, где вы помещаете (), чтобы фактически вызвать эту функцию и получить свое закрытие, и используете ли вы ключевое слово new.

1 голос
/ 08 октября 2009

Я не вижу существенной разницы между ними. Я предпочел бы последнее просто потому, что в нем гораздо меньше беспорядочных знаков препинания.

С другой стороны, подход «модульный шаблон», кажется, является наиболее распространенным и становится широко известным шаблоном (из-за роста JQuery). Возможно, было бы лучше придерживаться этого распознанного шаблона не потому, что он имеет больше технических преимуществ, чем другой подход, но просто потому, что он, вероятно, будет более узнаваемым (несмотря на сильную пунктуацию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...