骨干继承模式与sibings实例类继承同一个父类

Oli*_*ier 2 javascript inheritance class backbone.js

我在Backbone遇到了一些奇怪的事情:

普通父类的所有子类似乎都与其兄弟姐妹一起获得"引用"属性...... !!

检查这个简单的测试用例:

        var MyParentClass = Backbone.View.extend({
            items:['foo'],
            initialize: function() {
            }
        });

        var MyFirstChildrenClass = MyParentClass.extend({
            initialize: function() {
                MyFirstChildrenClass.__super__.initialize.apply(this, arguments);
                console.warn('MyFirstChildrenClass::initalize()');
                this.items.push('bar');
            }
        });

        var MySecondChildrenClass = MyParentClass.extend({
            initialize: function() {
                MySecondChildrenClass.__super__.initialize.apply(this, arguments);
                console.warn('MySecondChildrenClass::initalize()');
                console.warn(this.items); // expecting [foo] & getting [foo,bar] !
            }
        });


    var firstInstance = new MyFirstChildrenClass();
    var secondInstance = new MySecondChildrenClass();
Run Code Online (Sandbox Code Playgroud)

Der*_*ley 8

这是由JavaScript中对象文字的评估引起的.这一行:

items:['foo'],

立即计算数组,父类型/子类型都包含对同一对象的引用.

所有Backbone对象都使用对象文字扩展,以创建新类型.对象文字是关键:值对,其中键始终是文字键,一旦JavaScript解析器命中该行,就会计算值.因此,您将获得['foo']父类中数组的单个引用.对象在JavaScript中引用,每个子类都包含对同一数组的引用.

修复此问题的最简单方法是分配items给返回数组的函数(在您的情况下看起来不是一个好的选项)或者在父类的构造函数中指定数组(或者如果需要,则指定初始化方法) ):


Backbone.View.extend({
  constructor: function(){
    Backbone.View.prototype.constructor.apply(this, arguments);

    this.items = ['foo'];
  }
});
Run Code Online (Sandbox Code Playgroud)

有关对象文字和值的冗长讨论(在jQuery的上下文中,但这里适用相同的原则),请参阅我的博客文章:http://lostechies.com/derickbailey/2011/11/09/backbone-js-对象文字的视图事件,jQuery的和-EL /