OO Шаблон конструктора Javascript: неоклассический или прототип

43
задан Cheeso 27 November 2009 в 19:47
поделиться

5 ответов

Это похоже на не одноэлементную версию шаблона модуля , в которой частные переменные можно моделировать, используя преимущества JavaScript. «закрытия».

Мне нравится ( вроде ... ). Но я действительно не вижу преимуществ в частных переменных, сделанных таким образом, особенно когда это означает, что любые новые добавленные методы (после инициализации) не имеют доступа к частным переменным.

Плюс, он не использует преимущества прототипной модели JavaScript. Все ваши методы и свойства должны быть инициализированы КАЖДЫЙ раз при вызове конструктора - этого не происходит, если у вас есть методы, хранящиеся в прототипе конструктора. Дело в том, что использование обычного шаблона конструктор / прототип намного быстрее! Вы действительно думаете, что частные переменные позволяют снизить производительность?

Такая модель имеет смысл с шаблоном модуля, потому что она инициализируется только один раз (для создания псевдо-синглтона), но я не уверен, что это делает смысл здесь.

Используете ли вы этот тип шаблона конструктора?

Нет, хотя я использую его одноэлементный вариант, шаблон модуля ...

Считаете ли вы его понятным?

Да, он читается и довольно ясно, но я не Мне нравится идея сгруппировать все в такой конструктор.

А у вас есть лучший?

Если вам действительно нужны частные переменные, то обязательно придерживайтесь этого. В противном случае просто используйте обычный шаблон конструктор / прототип (, если вы не разделяете опасения Крокфорда перед комбинацией new / this ):

function Constructor(foo) {
    this.foo = foo;
    // ...
}

Constructor.prototype.method = function() { };

Другие похожие вопросы, касающиеся Дуга взгляды на тему:

16
ответ дан 26 November 2019 в 23:08
поделиться

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

  1. Если у меня есть только один из чего-то, я использую анонимные объекты:

     var MyObject = {
     myMethod: function () {
     // сделай что-нибудь
     }
    };
    
  2. Для нескольких вещей я использую стандартное прототипное наследование javascript

     var MyClass = function () {
    };
    MyClass.prototype.myMethod = function () {
     // сделай что-нибудь
    };
    
    var myObject = новый MyClass ();
    

(1) намного легче читать, понимать и писать. (2) более эффективен при наличии нескольких объектов. Код Крокфорда будет каждый раз создавать новую копию функций внутри конструктора. Замыкание также имеет обратную сторону - его труднее отлаживать.

Хотя вы теряете действительно частные переменные, вы ставите перед предполагаемыми частными членами префикс _ в качестве соглашения.

this ] - это, по общему признанию, сложная проблема в javascript, но ее можно обойти, используя .call и .apply , чтобы настроить ее правильно. Я также часто использую var self = this; для создания закрывающей переменной для использования в качестве this внутри функций, определенных внутри функции-члена.

MyClass.prototype.myMethod = function() {
    var self = this;

    // Either
    function inner1() {
        this.member();
    }
    inner1.call(this);

    // Or
    function inner2() {
        self.member();
    }
    inner2();
};
10
ответ дан 26 November 2019 в 23:08
поделиться

Do you use this kind of constructor pattern?

Nope

Do you find it understandable?

Yes, its very straight forward.

Do you have a better one?

I haven't watched the talk yet, but I will be getting to it shortly. Until then, I don't see the danger of using new and this, and here's why:

Without having heard his points, I can only assume that he suggests staying away from such things because of the nature of this, and how it is prone to change depending on the context in which a particular method is executed (directly upon the original object or as a callback, etc). As an educator, he may be teaching avoidance of these keywords because of the demographic of largely unaware and inexperienced developers who dabble in JavaScript without first grokking the nature of the language. For experienced developers who are intimately acquainted with the language, I'm not convinced that it's necessary to avoid this feature of the language, which grant it an amazing amount of flexibility (which is completely different from avoiding things like with). All that said, I'll be watching it now.

At any rate, when not using some sort of framework that supports automagic inheritance (like dojo.declare), or when writing a framework independent object, I currently take the following approach.

Definition:

var SomeObject = function() {
    /* Private access */
    var privateMember = "I am a private member";
    var privateMethod = bindScope(this, function() {
        console.log(privateMember, this.publicMember);
    });

    /* Public access */
    this.publicMember = "I am a public member";

    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod();
    }
};

Usage:

var o = new SomeObject();
o.privateMethodWrapper();

Where bindScope is a utility function similar to Dojo's dojo.hitch or Prototype's Function.prototype.bind.

7
ответ дан 26 November 2019 в 23:08
поделиться

В в его книге это называется функциональное наследование (стр. 52). Пока не пользуюсь. Это понятно, если вы изучаете javascript у Дугласа. Я не думаю, что есть подход лучше. Это хорошо, потому что:

  • позволяет программисту создавать закрытые члены

  • защищает закрытые члены и устраняет это в отличие от притворной конфиденциальности (закрытые члены начинаются с _)

  • делает наследование гладким и без лишнего кода

Однако у него есть некоторые недостатки. Вы можете прочитать больше об этом здесь: http://www.bolinfest.com/javascript/inheritance.php

6
ответ дан 26 November 2019 в 23:08
поделиться

Используете ли вы такой шаблон конструктора?

Я использовал эту скороговорку ранее, когда впервые изучал JavaScript и наткнулся на литературу Дугласа Крокфорда.

Считаете ли вы это понятным?

Пока вы разбираетесь в замыканиях, этот метод понятен.

У вас есть лучший?

Это зависит от того, чего вы пытаетесь достичь. Если вы пытаетесь написать библиотеку, которая будет максимально защищена от идиота, я могу полностью понять использование частных переменных. Это может помочь предотвратить непреднамеренное нарушение пользователями целостности вашего объекта. Да, временные затраты могут быть немного больше (примерно в 3 раза больше), но затраты времени - спорный аргумент, пока они не повлияют на ваше приложение. Я заметил, что тест, упомянутый в предыдущем посте ( test ), не учитывает, сколько времени требуется для доступа к функциям объекта.

Я обнаружил, что метод прототипа / конструктора обычно приводит к более быстрому время строительства, да, но это не обязательно экономит время при поиске. Использование цепочки прототипов для поиска функции требует дополнительных затрат по сравнению с привязкой функции непосредственно к используемому вами объекту. Поэтому, если вы вызываете много функций-прототипов и не создаете много объектов, возможно, имеет смысл использовать шаблон Крокфорда.

Я, как правило, не люблю использовать частные переменные, если я не пишу мой код для большой аудитории. Если я с командой людей, которые все являются способными программистами, я в целом могу поверить, что они ' Я буду знать, как использовать свой код, если я сам кодирую и хорошо комментирую. Затем я использую что-то вроде шаблона Крокфорда без частных членов / методов.

1
ответ дан 26 November 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: