Запутался в js proto и назначении новых свойств - PullRequest
1 голос
/ 05 февраля 2012

У меня есть простой объект (на самом деле кнопка в Sencha Touch). Он находится в объекте с именем'thing.aButton () ';

Этот объект содержит свойство с именем 'view' со значением 'home';

Теперь я хочу присвоить это переменной, назначить некоторые новые свойства и передать ее.

Итак, я делаю:

var c = something.aButton();

Теперь я назначу еще кое-что:

c.id = 4;
c.class = 'class';

Теперь проблема в том, что c.view не определен, если я не сделаю:

c.view = c.view;

Который - выходец из мира PHP сбивает с толку меня. Я знакомлюсь с основами прототипов, но не понимаю, как можно просто присвоить свой объект переменной для простоты использования и работы с этим. Я также не знаю всех исходных свойств, поэтому переназначить их так, как это невозможно в моем коде, и я почему-то сомневаюсь, что это правильный путь.

Если я вывожу 'c' на консоль, я вижу:

Ext.Object.classify.objectClass
class: "class"
id: 4
__proto__: Object
  view: 'home'
  ....

1 Ответ

3 голосов
/ 05 февраля 2012

Теперь я назначу еще кое-что:

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, движок смотрит на прототип.Вот что я имел в виду под живой системой.

...