Backbone.js模型中的数组本质上是静态的?

mik*_*ker 4 coffeescript backbone.js

为什么Backbone.js模型中的数组本质上是静态变量?

class exports.Content extends Backbone.Model
    tags: []
Run Code Online (Sandbox Code Playgroud)

然后如果我做几个模型:

contentA = new Content()
contentB = new Content()
Run Code Online (Sandbox Code Playgroud)

并为每个模型的数组添加一个字符串:

contentA.tags.push('hello')
contentB.tags.push('world')
Run Code Online (Sandbox Code Playgroud)

他们最终都得到了相同的数组:

contentB.tags // ['hello','world']
Run Code Online (Sandbox Code Playgroud)

但如果它是一个字符串,那么没有问题:

contentA.name = "c1"
contentB.name = "c2"

contentA.name // "c1"
Run Code Online (Sandbox Code Playgroud)

Der*_*ley 15

简短的回答

当您调用extends以定义对象时,您将新对象的配置作为对象文字传递.对象通过引用传递,并且该extends函数仅将对tags数组的引用传递给新类型定义.

如其他人所述,您可以通过分配tags功能来纠正此问题.这是有效的,因为函数会延迟tags对对象实例化的评估.JavaScript中没有任何本机可以做到这一点,但它的Backbone本身可以识别tags为函数或值.

答案很长

尽管您的代码在CoffeeScript中,但这归结为JavaScript中的一些组合:

  • JavaScript中没有类
  • 立即评估对象文字
  • JavaScript对象通过引用传递

在JavaScript中,没有类.期.CoffeeScript为您提供了类的概念,但实际上,它被编译为没有类的JavaScript.

您可以拥有类型和类型定义(构造函数),但不能使用类.Backbone提供类似于类的定义,看起来类似于Java的"扩展"基于类的继承.它仍然只是JavaScript,没有类.

相反,我们所拥有的是传递给extends方法的对象文字.这就像你编写这段代码一样:

var config = { tags: [] }

var MyModel = Backbone.Model.extends(config);

config

config

在此代码中,tags是对象文字,或散列,键/值对或关联数组.无论你怎么称呼它,它都是同样的基本理念.最终得到一个config.tags具有[]属性的对象.值extends是一个空数组extends,它本身就是一个对象.

这让我们回到简短的回答:

当您调用tags以定义对象时,您将新对象的配置作为对象文字传递.对象通过引用传递,并且该tags函数仅将对tags数组的引用传递给新类型定义.

如其他人所述,您可以通过分配tags功能来纠正此问题.这是有效的,因为函数会延迟extends对对象实例化的评估.JavaScript中没有任何本机可以做到这一点,但它的Backbone本身可以识别extends为函数或值.


ben*_*les 6

"tags"正在Content.prototype上声明 - 它在所有Content实例中共享.您可能需要使用默认值:http://backbonejs.org/#Model-defaults.但是,应该注意的是,在定义默认值时必须使用函数(而不是散列),否则在使用通过引用传递的类型(例如Array)时仍会遇到同样的问题.

var Content = Backbone.Model.extend({
  defaults: function() { 
    return {
      tags: []
    };
  }
});
Run Code Online (Sandbox Code Playgroud)