Неожиданные общие данные с использованием наследования прототипов JavaScript - PullRequest
1 голос
/ 30 июня 2011

Исходя из фона Java, я ожидаю, что свойства в базовом классе экземпляра класса будут уникальными для других экземпляров класса, использующих тот же базовый класс.

В javascript любые свойства, хранящиеся в "Базовый класс ", кажется, разделен между различными экземплярами этого" базового класса ".Например, см. Здесь:

http://jsfiddle.net/4waQV/

Как видите, к BaseView.settings можно получить доступ через ViewOne и ViewTwo.Изменение значения в BaseView.settings в одном случае влияет на значение в другом экземпляре.

Если я переместу settings: {} из BaseView в ViewOne и ViewTwo, все будет работать так, как яожидайте.

http://jsfiddle.net/4waQV/1/

Однако я не хочу загромождать ViewOne и ViewTwo дополнительными свойствами.Так что я могу динамически создавать this.settings внутри BaseView.setProp():

http://jsfiddle.net/4waQV/2/

Есть ли лучшие способы справиться с этим, или это хорошее решение?

Обратите внимание, что я использую представления Backbone.JS в этом примере, но я ожидаю, что любое решение наследования прототипов javascript получит аналогично.Вы можете видеть, что Backbone использует довольно типичные методы создания прототипического наследования:

https://github.com/documentcloud/backbone/blob/0.3.3/backbone.js#L870

https://github.com/documentcloud/backbone/blob/0.3.3/backbone.js#L955

1 Ответ

1 голос
/ 28 декабря 2011

Проблема здесь в том, что настройки наследуются от BaseView;наследуется, а не копируется.Если бы это было строковое значение, оно было бы по существу скопировано, но в массивах и объектах javascript они передаются по ссылке, а не по значению, поэтому, когда объект создается, он в конечном итоге указывает на тот же объект.

Исправлениечтобы создать метод инициализации в вашем BaseView и добавить эту строку:

this.settings = {};

Тогда, конечно, вы захотите убедиться, что вы вызываете инициализацию BaseView для каждого из ваших подпредставлений.Вы можете сделать это с помощью:

BaseView.prototype.initialize.apply(this, arguments);

например, http://jsfiddle.net/taxilian/PDmN8/1/

Обратите внимание, что этот метод инициализации элементов должен выполняться для всех элементов массива или объекта, иначе у вас возникнет та же проблема,Вы также можете создать конструктор и сделать это там, но я никогда не понимал, как это работает в классах Backbone, и не потратил время на то, чтобы по-настоящему сесть и разобраться = =

...