在模型中将默认设置为局部变量会导致未定义

时间:2014-08-15 09:33:09

标签: javascript backbone.js

当我运行默认trackName下面的代码时,artistName被设置为' undefined'

window.TrackDetailsModel = Backbone.Model.extend({
  NO_TRACK: 'No Track Set.',
  NO_ARTIST: 'No Artist Set.',

  defaults: {
    squareNumber: -1,
    trackName: this.NO_TRACK,
    artistName: this.NO_ARTIST,
    albumArt: './img/default.png'
  },

我可以通过在initialize方法中手动设置变量来解决这个问题,但我更愿意将其设置为默认值

  initialize: function() {
    this.set('trackName', this.NO_TRACK);
    this.set('artistName', this.NO_ARTIST);
  },

在默认部分访问之前未设置局部变量吗?或者我应该使用除了这个'之外的其他东西。用于访问this.NO_TRACK

2 个答案:

答案 0 :(得分:2)

您要传递给Backbone.Model.extend方法的对象

{
   NO_TRACK: 'No Track Set.',
   NO_ARTIST: 'No Artist Set.',
   defaults: {
       squareNumber: -1,
       trackName: this.NO_TRACK,
       artistName: this.NO_ARTIST,
       albumArt: './img/default.png'
}

this的不同背景。 this对象尚未应用于扩展主干模型,而是适用于扩展模型的上下文。

实施例

var foo = {
    value: 'something',
    fn: function() {
       window.TrackDetailsModel = Backbone.Model.extend({
           NO_TRACK: 'No Track Set.',
           NO_ARTIST: 'No Artist Set.',

           defaults: {
              squareNumber: -1,
              trackName: this.NO_TRACK,
              artistName: this.NO_ARTIST,
              albumArt: './img/default.png'
           }
       });
    }
}

foo.fn();

调用foo.fn()时,立即函数内的任何this值都适用于foo本身。所以你实际上在说foo.NO_TRACK,你可以看到它不存在。但是,如果您说artistName: this.value,那么它会正确地为艺术家名称

分配"something"

如果这不是变量的一部分(也就是说,它在全局范围内调用)那么this的值将是窗口对象,所以你实际上是在说window.NO_TRACK

您的问题的解决方案可能如下所示:

var d = {
    squareNumber: -1,
    trackName: 'No Track Set.',
    artistName: 'No Artist Set.',
    albumArt: './img/default.png'
}

window.TrackDetailsModel = Backbone.Model.extend({
    NO_TRACK: d.trackName,
    NO_ARTIST: d.artistName,
    defaults: d
});

然而,从逻辑上看你正在做什么,你在初始化时设置这些值的手动方法似乎是最正确的方法。 “首次创建模型实例时,请将曲目名称和艺术家名称初始化为这些值。”

答案 1 :(得分:1)

你做不到。对象文字不会创建新范围,因此this不引用当前模型,它引用另一个没有“NO_TRACK”属性的对象。您必须在initialize方法中设置值,或者创建基本模型并将其扩展。