Создание экземпляра объекта и функции в Backbone, js

Я взял на себя исследовательский проект, и у меня все хорошо, за исключением того, что в последнее время я думаю, что неправильно понимаю некоторую структуру JS, реализованную в Backbone. Я запутался в структуре модели или коллекции и в том, возвращает ли она объект или функцию.

Проект имеет эту текущую структуру для моделей:

define([…], function(…) {
  var measureModel = Backbone.Model.extend({
    defaults: {…},
    initialize: function(){…}
    …
  });
  return measureModel; //here there is no function, so I assume its an object
});

и для коллекций:

define([…], function(…){
  var measuresCollection = Backbone.Collection.extend({
    model: measureModel,
    initialize: function(){…}
  });
  return new measuresCollection(); //here I assume it is an function
});

Я сделал новые модели и коллекции с вышеуказанной структурой, но получил следующие ошибки, поэтому я также попробовал это:

define([…], function(…){
  return Backbone.Collection.extend({  // here I just return the Object
    model: newerModel,
    initialize: function(){…}
  });
});

Следуя этой первой структуре, в некоторых новых моделях и коллекциях я получаю ошибки Uncaught TypeError: object is not a function, Uncaught TypeError: [Object object] is not a function или Uncaught TypeError: undefined is not a function, в зависимости от пропуска конечного оператора возврата или просто возвращая объект напрямую.

Я вызываю конструктор в другом представлении так: this.newerCollection = new NewerCollection();

  • почему я получаю (любую) из этих ошибок, используя ту же структуру?
  • Каковы различия между созданием переменной и ее возвратом и просто возвратом ее напрямую?
  • почему я должен использовать один способ вместо другого?

person chris Frisina    schedule 09.07.2013    source источник
comment
Как вы создаете новые модели, используя первую структуру?   -  person Sushanth --    schedule 09.07.2013
comment
И this.newerCollection = new NewerCollection(); должно быть this.newerCollection = NewerCollection;, если вы возвращаете new measuresCollection()   -  person Sushanth --    schedule 09.07.2013
comment
Можете ли вы опубликовать весь код, с которым вы его тестируете?   -  person Sushanth --    schedule 09.07.2013
comment
Здесь - ветка htracks. В частности, я пытаюсь создать дополнительный раздел (systemLabelView.js) на странице, созданной из коллекции (labelsCollection.js) перетаскиваемых div, которые имеют представление о себе (SystemLabelButtonView.js), привязанное к модели (label.js) .   -  person chris Frisina    schedule 09.07.2013
comment
Если вы предпочитаете загружать страницу (даже с ошибками), я развернул здесь   -  person chris Frisina    schedule 09.07.2013


Ответы (1)


extend всегда возвращает функцию, которая используется в качестве конструктора для расширенной модели/коллекции/представления.

В этом блоке кода (первом в вопросе) вы возвращаете функцию, которая является конструктором для расширенной модели:

define([…], function(…) {
  var measureModel = Backbone.Model.extend({
    defaults: {…},
    initialize: function(){…}
    …
  });
  return measureModel; //here you are returning a function, which is a constructor for the extended Model
});

В этом блоке кода (втором в вопросе) вы возвращаете объект, а не функцию, потому что вы создали экземпляр measuresCollection с помощью new. Сама переменная measuresCollection является конструктором:

define([…], function(…){
  var measuresCollection = Backbone.Collection.extend({
    model: measureModel,
    initialize: function(){…}
  });
  return new measuresCollection(); //here you are returning an object because it is instantiated using `new`
});

Если вы попытаетесь использовать значение этого модуля для создания экземпляра нового объекта, вы получите ошибку «объект не является функцией».

В этом блоке кода (третий блок в вопросе) будет эквивалентно returning measuresCollection во втором блоке. Там вы возвращаете функцию, а не объект, как и в первом блоке.

define([…], function(…){
  return Backbone.Collection.extend({  // this is returning a function, the same as the first code block
    model: newerModel,
    initialize: function(){…}
  });
});

Если вы опустите оператор return в своем модуле, он вернет undefined, и вы получите ошибку «undefined is not a function» при попытке использовать его для создания экземпляра объекта.

По сути, нет никакой разницы между тем, как вы возвращаете конструкторы в 1-м и 3-м блоках кода. Первый просто присваивает конструктор локальной переменной перед его возвратом. Единственная причина сделать это - если вам нужно манипулировать им, прежде чем вернуть его.

person freejosh    schedule 09.07.2013
comment
так что же должно направлять меня между выбором возврата объекта и возвратом функции? - person chris Frisina; 10.07.2013
comment
Возврат объекта превращает модуль в синглтон. При первом запросе модуля он запускается и возвращается объект. Последующие разы объект в памяти используется. Поэтому, если вы хотите создать несколько экземпляров, верните функцию. - person freejosh; 10.07.2013