Устанавливая методы через объект прототипа или в конструкторе, различии? [дубликат]

18
задан Lightness Races with Monica 1 January 2012 в 03:46
поделиться

3 ответа

фокстрот и annakata оба корректны, но я добавлю свои 2 цента.

при использовании прототипа затем, каждый экземпляр "MessageClass" действительно ссылается на те же функции. Функции существуют в памяти только однажды и используются для всех экземпляров. Если Вы объявляете методы в конструкторе (или иначе добавьте его к определенному экземпляру), а не прототип затем новая функция создается для каждого экземпляра MessageClass.

Однако существует, вероятно, не любое значимое различие в производительности для большинства случаев, и маловероятно, что Вы будете видеть различие в использовании памяти также. Я пошел бы с опытным методом, если у Вас нет неопровержимого довода, чтобы сделать иначе. Единственная причина я могу вещь, что Вы могли бы хотеть объявить метод в конструкторе, состоит в том при необходимости в закрытии. Например, если Вам хотели обработчики событий, или Вы для моделирования частных собственностей с методами считывания/методами set Вы могли бы сделать:

function MessageClass() {
    var self = this;
    this.clickHander = function(e) { self.someoneClickedMe = true; };

    var _private = 0;
    this.getPrivate = function() { return _private; };
    this.setPrivate = function(val) { _private = val; };
}

РЕДАКТИРОВАНИЕ: , поскольку была дискуссия о том, как это производит объекты, расширенные другим объектом с помощью функций, присвоенных в конструкторе, я добавляю немного больше детали. Я мог бы использовать термин "класс" для упрощения обсуждения, но важно отметить, что js не поддерживает классы (который не означает, что мы не можем сделать хорошей разработки OO), или мы не обсудили бы этот вопрос.

Большинство библиотек JavaScript вызывает конструктора на базовом классе и sub классе. (например, Prototype.js's Object.extend) Это означает, что методы, присвоенные в конструкторе каждого, будут доступны на полученных объектах. Однако при расширении объектов сами могут быть неожиданные последствия.

, Если я беру MessageClass выше и расширяю его:

function ErrorMessageClass() {}
ErrorMessageClass.prototype = new MessageClass();

errorMsg = new ErrorMessageClass();

Затем errorMsg будет иметь getPrivate и setPrivate метод на нем, но они не могут вести себя, как Вы ожидали бы. Поскольку те функции были ограничены по объему, когда им присвоили (т.е. в "ErrorMessageClass.prototype =, новые MessageClass ()" не только являются get/setPrivate совместно использованными методами, _private переменная совместно используется через все экземпляры ErrorMessageClass также. Это по существу делает _private статическим свойством для ErrorMessageClass. Например:

var errorA = new ErrorMessageClass();
var errorB = new ErrorMessageClass();
errorA.setPrivate('A');
console.log(errorA.getPrivate()); // prints 'A'
console.log(errorB.getPrivate()); // prints 'A'
errorB.setPrivate('B');
console.log(errorA.getPrivate()); // prints 'B'

Аналогично с clickHandler функционируют и someoneClickedMe свойство:

errorA.clickHandler();
console.log(errorA.someoneClickedMe); // prints 'true'
console.log(errorB.someoneClickedMe); // prints 'true'

Однако изменение те функциональные определения для использования этого. _ частный:

this.getPrivate = function() { return this._private; };
this.setPrivate = function(val) { this._private = val; };

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

errorA.setPrivate('A');
errorB.setPrivate('B');
console.log(errorA.getPrivate()); // prints 'A'
console.log(errorB.getPrivate()); // prints 'B'
31
ответ дан 30 November 2019 в 07:00
поделиться

При привязке методов прототипом, JS только должен сделать это однажды и связывает с классом объекта (который делает его имеющим право на OO расширения JS).

, Если Вы делаете привязку в функции "класса", JS должен сделать работу создания и присвоения для каждого экземпляра.

6
ответ дан 30 November 2019 в 07:00
поделиться

Различие - при получении класса из Класса сообщений. Только методы, объявленные на прототипе, будут доступны на дочерних классах сообщения.

5
ответ дан 30 November 2019 в 07:00
поделиться
Другие вопросы по тегам:

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