Определение всех открытых методов или прототипа отдельных методов? - PullRequest
1 голос
/ 23 июля 2011

Поэтому, когда я делаю библиотеку, я обычно делаю это следующим образом:

var myLib = (function() {
    return {
        publicProperty: 'test',
        publicMethod: function() {
            console.log('public function');
        },
        anotherMethod: function() { //... },
        // .. many more public methods
    };
}());

Я слышал, что создание библиотек происходит быстрее и / или использует меньше памяти для инициализации, если вы пишете это так:

var MyLib = function() {
   this.publicProperty = 'test';
};

MyLib.prototype = {
    publicMethod: function() {
        console.log('public method');
    },
    anotherMethod: function() { //... },
    // ... many more public methods
};

myLib = new MyLib();

Одна инициализируется быстрее, чем другая?Мой вопрос вообще имеет смысл?Я предполагаю, что они выполняют ту же задачу (эта задача, которую я выполняю и использую myLib.publicMethod() где-то еще в моем коде на docready).Спасибо!

Ответы [ 2 ]

2 голосов
/ 23 июля 2011

Редактировать: Глядя на изменения в вопросе, я спрашиваю вас:

  • Планируете ли вы иметь несколько «экземпляров» вашей библиотеки одновременно?

Если вы этого не сделаете, я не вижу никакой пользы от использования конструктора, у вас будет только один объект, нет смысла определять свойства его прототипа - они все равно будут определены и использованы для одного объекта -.

Использование наследования будет полезно в том случае, если вы хотите иметь несколько экземпляров объекта, методы будут совместно использованы, повторно использованы и объявлены только один раз - выше в цепочке прототипов.


В вашем втором примере есть несколько проблем:

var myLib = (function() {
   this.publicProperty = 'this';
}());

Переменная myLib будет содержать только undefined - вы ничего не возвращаете из выражения функции-, а ваш publicProperty будет определен как свойство глобального объекта, так как при выполнении этого функция, this будет привязана к глобальному объекту.

Кроме того, если код выполняется в строгом режиме , значение this в этом случае будет undefined, а выражение доступа к вашему свойству просто выдаст TypeError - хорошая вещь IMO, так как я почти уверен, что вы не хотите объявлять publicProperty как член глобального объекта -.

myLib.prototype = {
    publicMethod: function() {
        console.log('public method');
    },
    anotherMethod: function() { //... },
    // ... many more public methods
};

Доступ к свойству prototype здесь не удастся - помните, myLib - это undefined -.

Значение prototype имеет смысл только для функций , используемых для функций конструктора -функций, предназначенных для использования с оператором new - я думаю, вы путаете это свойство с внутренним свойством [[Prototype]], которое есть у всех объектов.

Определение свойства с именем prototype для нефункционального объекта не будет иметь никакого эффекта.

Смотри также:

2 голосов
/ 23 июля 2011

Два скрипта дают разные результаты.

В первом вы создаете объект myLib с тремя (или более) свойствами.Его прототип - Object.prototype.Дело в том, что вы создали один объект.

Во втором вы создаете глобальную переменную с именем publicProperty.Это, вероятно, не то, что вы хотели.(РЕДАКТИРОВАТЬ: OP Вопрос исправлен, это больше не проблема.)

Тем не менее, предполагая, что вы намеревались создать объект с методами в прототипе, ваш код, вероятно, медленнее на простом движке JavaScript, потому что вызов методов впрототип требует прохождения ссылки от объекта к прототипу.

Теперь, если ваше намерение состоит не в том, чтобы сделать один, а в том, чтобы создать множество экземпляров из myLib, тогда вы сохранитемного памяти, помещая методы в прототип, потому что у вас будет одна копия каждой функции.Вы не хотите тысячи копий методов.:)

РЕДАКТИРОВАТЬ НА АДРЕС OP OP QUESTION :

Относительно двух подходов и как сделать первый "быстрее":

Теоретически у вас естьпространственно-временной компромисс.Помещая методы непосредственно в объект, у вас нет поиска цепочки прототипов.Но недостатком является то, что каждый экземпляр имеет свою собственную копию методов.Если вы создаете несколько экземпляров, вы должны определить каждый из методов один раз и поместить их в прототип.Современные (класс V8) JavaScript-движки довольно хороши с такими вещами, поэтому вам не следует искать оптимизации скорости, упаковывая методы в объект.Теперь, для синглетонов , идите вперед и заполните объект.Другой подход - поместить все методы в myLib и создать экземпляры с Object.create(myLib).Это делает myLib самим прототипом для всех «экземпляров» и обычно считается хорошей формой (по крайней мере, если вы будете следовать рекомендациям «Хороших деталей», которые я обычно делаю).

...