了解Backbone扩展

时间:2014-04-29 19:48:35

标签: javascript inheritance backbone.js prototype javascript-objects

我是Backbone的忠实粉丝,但最近在Backbone的延伸中遇到了一些奇怪的行为。我之所以称之为奇怪,可能是因为误解了意图,而不是理解javascript如何运作的深刻细节。 长话短说,修改任何实例的属性会在重新实例化对象时重置为默认值,修改子属性会为将来的所有实例更改它。我很乐意深入了解此事。

以下是一些使用Backbone扩展的代码:

var myObj = function () {
    this.a = true;
};

myObj.extend = extend; //the backbone version, link provided at bottom

//the pattern used throughout backbone
var myExtension = myObj.extend({
    b: "hello"
});

var instance1 = new myExtension();
instance1.b = "goodbye";

var instance2 = new myExtension();
console.log(instance2.b); //logs hello!!

var myBadExtension = myObj.extend({
    b: {
        c: "hello"
    }
});

var bad1 = new myBadExtension();
bad1.b.c = "goodbye";

var bad2 = new myBadExtension();
console.log(bad2.b.c); //!!! logs "goodbye" !?!?!?!

非常感谢任何和所有帮助。

Link to backbone extend

1 个答案:

答案 0 :(得分:3)

是的,因为bad2.bbad1.b是同一个对象,来自他们的共享原型。为避免这种情况,您应在b方法中为initialize分配一个值。

var myBadExtension = myObj.extend({
    initialize: function() {
      this.b = {
        c: "hello"
      };
    }
});

如果属性是原始的(IOW不是对象或数组),那么无关紧要,但我认为以相同的方式初始化基元更为常见。

鉴于您没有使用骨干的内置类,这可能有更好的工作机会。

var myBadExtension = myObj.extend({
  constructor: function() {        
    myObj.apply(this, arguments);

    this.b = {
      c: "hello"
    };
  }
});