@alexnotonfire

Когда использовать методы в конструкторе, а когда — в прототипе?

Я не понимаю, в каких случаях необходимо метод объекта объявлять в самом конструкторе, а когда - в прототипе.

Вот например в коде ниже я не вижу разницы между двумя методами и хотелось бы чтобы кто-то пролил свет на их использование.

function A() {
  this.method = function() {
    alert('Метод конструктора');
  }
}

A.prototype.method2 = function() {
	alert('Метод прототипа');
}

let object = new A();


Известно ведь, что в новом стандарте ES6 с синтаксисом классов и вовсе нет методов в конструкторе.
  • Вопрос задан
  • 1003 просмотра
Решения вопроса 3
EShein
@EShein
Shein
Например у вас есть 1000 объектов, у каждого объекта в конструкторе есть метод который делает одно и тоже для каждого объекта. Занимает память? думаю да. Можно в прототип вынести этот метод и метод будет всего один для каждого объекта, а к нему будут вести ссылки. С точки зрения оптимизации так будет лучше.
Ответ написан
mudrenokanton
@mudrenokanton
frontend dev
Чисто технически, в конструктор могут прилететь свойства, которые будут участвовать в создании методов(методы в своем замыкании будут хранить их значения), а в инстанс самого объекта они не попадут, потому и методы прототипа к ним достучаться не смогут. И еще одно отличие в shadowing-e, если у инстанса есть метод и с таким же названем есть еще и метод в прототипе, то вызовется метод инстанса.

А на деле, если есть цепочка наследования, то наследуются от .prototype через Object.create(), т.е. методы контруктора унаследованы не будут. Удобно, если мы этого не хотим (но так тоже бывает редко, потому что обычно вызывается родительский конструктор).
Ответ написан
Комментировать
SnaIP
@SnaIP
Front-end разработчик
Во первых при создание метода в конструкторе, вы переопределяете каждый раз его.
Во вторых как говорилось выше, зачем вам для каждого объекта создавать свой метод, когда лучше обратится по цепочке прототипов к нему.

Вот простой пример как лучше делать es5

var root = document.getElementById('root');

// наш конструктор
function FabricButton(options) { 
    this.element = document.createElement('button');
    this.element.innerHTML = (typeof options.text == 'string') ? options.text : 'there had to be text';
    this.element.style.color = (typeof options.color == 'string') ? options.color : 'blue';
}

// выносим метод нашего класса в прототип, чтобы при создание не перезаписывать его
FabricButton.prototype.render = function(root) {
  root.appendChild(this.element);
}

function FabricButtonPopup(options) { 
    FabricButton.call(this, options);
    this.element.addEventListener('click', this.popup);
}

// Здесь наследуем наш прототип, то есть сюда попадет {constructor: f, render: f} 
FabricButtonPopup.prototype = Object.create(FabricButton.prototype);
FabricButtonPopup.prototype.constructor = FabricButtonPopup; // переопределяем ссылку на наш конструктор

FabricButtonPopup.prototype.popup = function() {
  prompt('open window')
}

var button = new FabricButton({
  text: 'press here',
  color: null
})

var buttonPopup = new FabricButtonPopup({
  text: 'press here man',
  color: 'red'
})
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
k12th
@k12th
console.log(`You're pulling my leg, right?`);
Известно ведь, что в новом стандарте ES6 с синтаксисом классов и вовсе нет методов в конструкторе.

Отчего же?
class Cls {
  constructor() {
    this.method = () => { console.log('hello!') }
  }
}

Другое дело, что смысла в этом нет. Почти всегда можно определить метод и это будет красивее (читай, проще в поддержке) и быстрее, чем навешивание методов на инстанс.
Ответ написан
Комментировать
leni_m
@leni_m
ЧупаКобрус
когда надо использовать методы в конструкторе - используем методы в конструкторе, а когда надо в прототипе - используем в прототипе.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы