Edit: Добавлено несколько больше на конец и сделал коррекцию
Мне кажется, что нам нужно ответить здесь. Прошу прощения, если это плохой этикет (и если это неправильный ответ). Пожалуйста, дайте мне знать.
Пути Прототипом работает наследование в JavaScript:
Когда вы прочитать свойство объекта, позволяет сказать tires
свойства вашего Car
объекта, сначала он проверяет Car
есть что само свойство. Что это означает, есть ли свойство tires
, которое напрямую связано с объектом ? Или, другими словами, это Car
что-то вроде этого:
{
tires: 0,
...
}
И ответ нет. Можно подумать, Object.create()
делает это, похоже на то, что вы могли бы сделать в конструкторе, т.е.
function Vehice(t) {
this.tires = t;
...
};
var Car = new Vehicle(4);
Все Object.create()
делает делает объект вы передаете в prototype
объекта он возвращается к вам.
Таким образом, после Object.create()
ваш объект выглядит примерно так
{
__proto__: //reference to vehicle
}
Так что, когда он не находит tires
непосредственно присоединенные к объекту, он смотрит на прототипе, в этом случае ссылка на vehicle
объект, который вы создали ранее. Прототип (vehicle
) имеет, имеет свойство tires
, поэтому оно возвращает это значение.
Коррекция
Так что же происходит, когда вы говорите Car.tires = 6
?Когда вы напишите значение свойства объекта, все будет работать по-другому. Javascript только смотрит, есть ли у объекта этот объект для записи. Если сам объект не имеет этого свойства, он сначала проверяет цепочку прототипов, чтобы убедиться, что свойство не является унаследованным только для чтения. Если это не так, то создает это свойство на самом объекте (до тех пор, пока законно писать это свойство для объекта). Так что теперь у вас есть что-то, что выглядит следующим образом:
{
tires: 6,
__proto__: //reference to vehicle
}
Конец коррекция
Теперь, когда вы читаете tires
свойства на Car
объекта, он первый видит tires
свойства на самом Car
объекта и возвращает это значение, никогда не нужно смотреть на прототип.
Вот почему вы можете установить tires
на одном транспортном средстве, а не влиять на стоимость других.
Сейчас для seats.total
Недвижимость. Когда вы читаете из свойства seats
, все работает по-прежнему. Не существует свойства seats
на самом объекте Car
, поэтому он смотрит на прототип, который у него есть. Затем он проверяет объект, на который ссылается seats
, чтобы увидеть, имеет ли он свойство total
, к которому он прикреплен, и он делает это, поэтому он просто возвращает это значение.
Теперь, когда вы хотите написать в собственность total
, все снова и снова. Заявление таково: Car.seats.total = 4
. Что здесь происходит, так это то, что вы устанавливаете свойство total
на объект , на который ссылается seats
объект.
Javascript сначала должен найти объект, на который ссылается seats
. Он делает это, проверяя, является ли это свойством самого объекта Car
. Это не так, поэтому он проверяет прототип, где он находит свойство seats
. Теперь он может записать свойство total
объекту seats
, как мы видели ранее, но обратите внимание, что это происходит с свойством seats
прототипа, который является реферином для объекта vehicle
, определенного ранее и разделяемого bike
.
Другими словами, JavaScript не видит, что вы пишете в собственность Car
объекта, поэтому он не создает seats
свойство на Car
объекта и присвоить ему новый объект, а затем в total
собственности на этот объект и назначить его 4
.
Теперь, когда вы пытаетесь прочитать bike
«s seats
свойства, JavaScript сначала ищет, чтобы увидеть, если bike
имеет seats
свойство непосредственно присоединенную к нему. Это не так, поэтому он выглядит прототипом bike
, который имеет его и возвращает измененный объект vehicle.seats
.
Надеюсь, это разъяснит, что происходит и отвечает на ваши вопросы. Дайте мне знать, если какая-либо часть не ясна, и я надеюсь, что кто-то меня исправит, если я просто ошибаюсь!
Добавление: Я думаю, исходя из традиционного языка OO, как она работает для tires
является то, что можно было бы ожидать, чтобы случиться: Вы унаследовать начальное значение, но если вы измените его, вы не ожидаете, что изменить для каждого другого экземпляра vehicle
.
Способ, которым javascript делает это очень экономично. Только изначально у прототипа есть свойство, если у вас есть тысяча объектов, наследующих от vehicle
, и только 2 из них устанавливают свойство tires
, вы использовали только пространство для трех Number
s вместо тысячи.
Что касается, как она работает с seats
, я полагаю, что они могли бы спроектировали язык, чтобы обнаружить, если вы настраивали свойство на унаследованные object
(seats
), а затем скопировать весь объект в экземпляр. Я предполагаю, что это фактически сделает систему менее гибкой и более сложной. Если вы хотите Car
иметь свою собственную версию seats
, вы можете указать его следующим образом:
var car2 = Object.create(vehicle, {
seats: {
value: {
count: vehicle.seats.total
}
}
});
или вот так:
var car2 = Object.create(vehicle);
car2.seats = { count: vehicle.seats.total }; //create a new object like the one attached to vehicle
, что последний пример сделать ли яснее, что происходит?
Для меня в этом случае явная версия конструктора этого будет более естественной, но с javascript мы можем использовать конструкторы или `Object.create() или различные комбинации из них, чтобы делать то, что нам нужно.
В конечном счете, каждый комплект происходит в двух частях. Сначала найдите объект, на который мы устанавливаем свойство; Наконец, установите свойство. Все до этого окончательного .
только там, чтобы сделать первый шаг:
Car.seats.count = 10
означает установить count
свойство объекта, указанного на Car.seats
10. Какой объект является Car.seats
? Мы теперь следуем правилам , читающим свойство, а не письмо. Car
не имеет свойства seats
, поэтому см., Если он наследует один. Если это не так, Car.seats
вернет undefined
, и попытка установить свойство на undefined
вызовет ошибку. Если он наследует его, Car.seats
вернет объект откуда-то вниз по цепочке прототипов, в этом случае объект, на который ссылается vehicle
. Этот объект имеет свойство count
так просто установить его на 10.
Car.tires = 4
означает установить tires
свойства объекта, указанный на Car
до 4. Car
не имеет tires
свойства, поэтому убедитесь, что мы позволили создать один, а затем сделать это.
Надеюсь, это прояснит ситуацию. Извините за то, что написал так много, но это действительно помогло укрепить эти концепции для меня. Плюс я узнал некоторые материалы ECMAScript 5, которые я блаженно игнорировал :-)
нет, это не для меня – Sankara
Я вижу вашу проблему сейчас. Кажется, что «Car.seats.total» не было установлено. На самом деле это не проблема: проблема в том, что 'bike.seats' переписывает' Car.seats'. – lonesomeday
Да, именно это мой вопрос, почему он переписывается? – Sankara