Backbone 模型对象在获取期间具有未定义的原型 属性

Backbone Model object has undefined prototype property during fetch

我正在尝试定义一个 Backbone 集合,然后使用 Backbone.fetch 从 API 中提取数据。但是当我 运行 获取集合时,我最终得到了这个错误:

当我进一步检查控制台中的问题时,我发现 Backbone 试图确定模型的唯一键时 Backbone.create 函数中的错误。由于某种原因,模型的 prototype 属性 未定义:

...即使模型本身已定义:

我有点困惑,为什么 prototype 属性 是未定义的。我在上面找到了一个类似但日期为 post 的,但产生错误的情况似乎有很大不同。

令我感到特别奇怪的是,在控制台中我能够找到代码所需的 idAttribute 属性,它实际上嵌套了两层,因此它应该可以通过 this.model.__proto__.__proto__.idAttribute 访问,因为 this.model.__proto__.__proto__ 指向 Backbone.Model:

不用说了,我有点糊涂了,不了解Backbone的内幕。如果有人能阐明这里可能出现的问题,那就太好了。我的 Backbone 模型和集合定义在这里:

(function() {
    'use strict';

    var Backbone = require('backbone');
    var _ = require('underscore');

    var Recommendation = new (Backbone.Model.extend({

        defaults: {
            id: '',
            rating: 0
        };

    }));

    var RecommendationStore = new (Backbone.Collection.extend({

        model: Recommendation,

        url: '/recommendations',

        initialize: function() {
            console.log('RecommendationStore::initailize()');
            var self;

            self = this;

            this.fetch({ 
                data: $.param({ user: '55587bd9a3f34012351fd71c'}),
                success: function(collection, response, options) {
                    console.log(this);
                }
            });

        },

    }));

    module.exports = RecommendationStore;

}());

在进一步思考 Javascript 对象和原型的性质后,我发现了这里的问题。这就是我的理解,尽管我可能有点偏离。

基本上,在 Javascript 中,可以在 constructor 对象上访问 prototype 属性。根据 definition in the ECMA 5.1 spec a 的构造函数对象是:

[f]unction object that creates and initialises objects.

在 Backbone 中,模型是构造函数对象,因此抛出错误的代码会尝试调用 this.prototype(即 constuctor.prototype)。但是,在我的代码中,我实际上将一个由该构造函数对象创建的新对象分配给了模型名称:

var Recommendation = **new** (Backbone.Model.extend({

    defaults: {
        id: '',
        rating: 0
    };

}));

所以在这种情况下,分配给我的变量 Recommendation 的对象实际上不是构造函数,因此没有 prototype 属性。因此错误。为了解决这个问题,我只是将构造函数分配给 Recommendation,如下所示:

var Recommendation = Backbone.Model.extend({

    defaults: {
        id: '',
        rating: 0
    };

});