Неожиданный конструктор / расширение поведения в BackboneJS - PullRequest
1 голос
/ 09 марта 2012

Действительно запутался в том, как работает JavaScript / BackboneJS.Давайте рассмотрим следующий пример:

window.MyView = Backbone.View.extend({
    index: 0,
    list: [],        
    initialize: function () {
        console.log("Initializing MyView");
        console.log("this.index = " + this.index);
        console.log("this.list = [" + this.list.join(',') + "]");
        this.index++;
        this.list.push(this.index);
    }
});

var first = new MyView(),
    second = new MyView();

Здесь я ожидал, что новый MyView () создаст чистую копию window.MyView "class", поэтому результат будет:

Initializing MyView
this.index = 0
this.list = []

Initializing MyView
this.index = 0
this.list = []

Но вместо этого у меня есть

Initializing MyView
this.index = 0
this.list = []

Initializing MyView
this.index = 0
this.list = [1] // Very unexpected!

Запутанная часть заключается в том, что целочисленная переменная "index" была фактически 0, как и ожидалось, но массив "list" уже содержал значение из предыдущей инициализации.Как это получается?

Демо http://jsfiddle.net/fqZTp/3/

1 Ответ

3 голосов
/ 09 марта 2012

Различное поведение между тем, что происходит с list и index, хорошо объясняется с помощью этих двух ответов:

Чтобы суммировать их:

  • list и index существуют на прототипе MyView.
  • После создания new MyView(), initialize() работает в контексте вновь созданного экземпляра (т.е. не прототипа).
  • Когда вы push() что-то вводите в list, вы помещаете это в объект списка, на который ссылается на прототип. Вы вообще не обновляете ссылку на список, просто читаете ее.
  • Когда вы index++, это на самом деле выполняет назначение (this.index = this.index + 1) за кадром. Когда вы назначаете что-либо объекту, не имеет значения, существует ли он в прототипе или нет - вы назначаете это конкретному экземпляру . Прототип не меняется.
<Ч />

Для ожидаемого поведения просто установите оба свойства в функции initialize:

window.MyView = Backbone.View.extend({
    initialize: function () {
        this.index = 0;
        this.list = [];

        this.index++;
        this.list.push(this.index);
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...