我是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" !?!?!?!
非常感谢任何和所有帮助。
答案 0 :(得分:3)
是的,因为bad2.b
和bad1.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"
};
}
});