Как пример шаблона прототипа Йегге обрабатывает переменные экземпляра?

Мне понравился шаблон прототипа Стива Йегге, и я решил быстрое доказательство концепции примера.

Однако я не особо все продумывал. Хотя он отлично подходит для динамического определения поведения объектов и является простым решением для самоуверенного эльфа Стива, я все еще пытаюсь найти лучший способ обработки переменных экземпляра.

Например, допустим, у меня есть объект AwesomeDragon. Затем я хочу создать объект AwesomeDragonImmuneToFire, поэтому я создаю новый дочерний элемент AwesomeDragon (AwesomeDragonImmuneToFire наследует свойства от AwesomeDragon) и «помещаю» «ImmuneToFire» в качестве свойства со значением «true». Все идет нормально. Теперь предположим, что я хочу отправить свой объект AwesomeDragon в путешествие по близлежащим крестьянским деревням. Это потребует обновления свойства «position» AwesomeDragon. Однако в тот момент, когда я сделаю это, AwesomeDragonImmuneToFire также взлетит.

Является лучшим решением для переопределения значений экземпляра при создании объекта, например. немедленно «поместить» значение «position» в AwesomeDragonImmuneToFire к текущему «полученному» значению «position»?


person Matt Mitchell    schedule 23.10.2008    source источник


Ответы (2)


Разве это не зависит от того, как вы на самом деле реализуете наследование в вашей системе?

Например, в версии JavaScript того, что вы описываете, prototype вместо AwesomeDragonImmuneToFire обычно будет экземпляром AwesomeDragon, и, поскольку вы всегда будете работать с экземплярами, не имеет значения, что вы делать с любым конкретным AwesomeDragon:

function Dragon()
{
    this.position = "starting point";
}

function AwesomeDragon()
{
    this.awesome = true;
}
AwesomeDragon.prototype = new Dragon();

function AwesomeDragonImmuneToFire()
{
    this.immuneToFire = true;
}
AwesomeDragonImmuneToFire.prototype = new AwesomeDragon();

>>> var awesome = new AwesomeDragon();
>>> var immune = new AwesomeDragonImmuneToFire();
>>> awesome.position = "flying above village";
>>> immune.position;
"starting point"
>>> immune.awesome
true

В этом примере нет классов, и все экземпляры являются просто экземплярами Object, которые знают, какая функция использовалась для их создания. new — это просто немного синтаксического сахара, а использование StudlyCaps для функций-конструкторов — это просто соглашение для функций, которые предназначены для использования с new.

Ключевым моментом является то, что каждый объект имеет цепочку объектов-прототипов, которая проверяется, если вы пытаетесь получить доступ к атрибуту, которого сам объект не содержит, в соответствии с описанием Йегге того, что такое «шаблон свойств».

https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model

person Jonny Buchanan    schedule 23.10.2008
comment
Я думал, что идея прототипов заключалась в том, что не было настоящих классов — только экземпляры класса-прототипа. Я думаю, гибридный принцип может работать нормально, но я беспокоюсь, что тогда вам придется проверять методы объекта и свойства прототипа. - person Matt Mitchell; 23.10.2008
comment
Кстати, спасибо за отзыв - мне понравился ваш пример, и я проголосовал за него. - person Matt Mitchell; 23.10.2008
comment
Есть действительно только экземпляры. Однако экземпляр Awesome, используемый в качестве прототипа, и экземпляр Awesome, используемый в рабочем процессе, могут отличаться, как в примере выше. - person Pavel Feldman; 13.11.2008

Это потребует обновления свойства «position» AwesomeDragon. Однако в тот момент, когда я сделаю это, AwesomeDragonImmuneToFire также взлетит.

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

person Vincent Ramdhanie    schedule 23.10.2008
comment
В прототипе свойства шаблона наследуются от родительского объекта. Поэтому, пока я не определяю позицию для AwesomeDragonImmuneToFire, она наследует позицию AwesomeDragon. - person Matt Mitchell; 24.10.2008