Как пример прототипа Yegge обрабатывает переменные экземпляра? - PullRequest
6 голосов
/ 23 октября 2008

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

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

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

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

Ответы [ 2 ]

10 голосов
/ 23 октября 2008

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

Например, в версии 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

1 голос
/ 24 октября 2008

Это будет включать в себя обновление свойства 'position' AwesomeDragon. Однако, как только я это сделаю, AwesomeDragonImmuneToFire тоже взлетит.

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

...