Теперь я назначу еще кое-что:
c.id = 4;
c.class = 'class';
Я бы не использовал идентификатор class
.Это зарезервированное слово в 3-м издании JavaScript и в «свободном» (нестрогом) коде в 5-м издании.
Теперь проблема в том, что c.view не определен, если я не сделаю:
c.view = c.view;
Это не неопределенно.Здесь вы меняете то, что c
имеет свою собственную копию свойства view
.Если бы вы только что сделали console.log(c.view)
, вы бы увидели его значение в консоли, даже не выполнив вышеуказанного присваивания.
Способ работы прототипов в JavaScript заключается в том, что объект резервируется прототипом в жить путь.Поэтому, если вы берете значение view
из c
, а c
не имеет своего собственного свойства, называемого view
, проверяется его цепочка прототипов.Но если вы присваиваете значение view
для c
, тогда c
получает свойство своего собственного с этим именем, и вы видите его в дампах объектов и т. Д..
Итак, вот упрощенный пример:
function Foo() {
}
Foo.prototype.bar = "42";
var f = new Foo();
console.log(f.bar); // "42"
В данный момент наш граф объектов выглядит так:
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| | | bar: "42" |
+-----------+ +---------------+
Итак, у нас есть f
,который подкреплен прототипом Foo.prototype
.Когда мы спрашиваем f
о свойстве bar
, так как f
не имеет собственного свойства с таким именем, движок JavaScript смотрит на свой прототип, чтобы узнать, действительно ли это .Если так, то это значение используется.(И это продолжается, если у прототипа есть прототип и т. Д.)
Теперь предположим, что мы делаем это:
f.bar = "43";
console.log(f.bar); // "43"
Поскольку f
теперь имеет собственный bar
свойство, движок JavaScript использует значение этого свойства.Теперь наш график выглядит следующим образом:
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| bar: "43" | | bar: "42" |
+-----------+ +---------------+
Мы можем удалить свойство f
:
delete f.bar; // `delete` removes "own" properties from objects
console.log(f.bar); // "42"
... и получить, таким образом, bar
из f
снова обращается к прототипу, потому что f
не имеет свойства с именем bar
.Мы вернулись к исходному графу объектов:
+-----------+ +---------------+
| f |----->| Foo.prototype |
|-----------| |---------------|
| | | bar: "42" |
+-----------+ +---------------+
Теперь самое интересное: предположим, мы изменили свойство прототипа?
Foo.prototype.bar = "baz";
console.log(f.bar); // "baz"
, поскольку f
не имеет свойства bar
, движок смотрит на прототип.Вот что я имел в виду под живой системой.