【问题标题】:Backbone inheritance pattern with sibings instance of class inheriting of the same parent具有相同父类的兄弟实例的骨干继承模式
【发布时间】:2012-03-18 23:52:13
【问题描述】:

我在 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();

【问题讨论】:

    标签: javascript class inheritance backbone.js


    【解决方案1】:

    这是由 JavaScript 中的对象字面量求值引起的。这一行:

    items:['foo'],

    立即评估数组,并且父类型/子类型都持有对同一对象的引用。

    所有 Backbone 对象都使用对象字面量进行扩展,以创建新类型。对象字面量是键:值对,其中键始终是字面键,并且只要 JavaScript 解析器命中该行,就会评估该值。因此,您将在父类中获得对数组 ['foo'] 的单一引用。对象在 JavaScript 中是通过引用来实现的,您的每个子类都将包含对同一个数组的引用。

    解决此问题的最简单方法是将 items 分配给返回数组的函数(在您的情况下这似乎不是一个好的选择)或在父类的构造函数中分配数组(或初始化方法,如果需要):

    
    Backbone.View.extend({
      constructor: function(){
        Backbone.View.prototype.constructor.apply(this, arguments);
    
        this.items = ['foo'];
      }
    });
    

    有关对象字面量和值的冗长讨论(在 jQuery 的上下文中,但此处适用相同的原则),请参阅我的博客文章:http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/

    【讨论】:

    • 非常感谢这个非常清晰和有启发性的答案。我要去 this.items = _.clone(this.items);在构造函数中,你认为这适合/工作吗?
    • 那会很完美。您将在每个实例中获取原始 .items 的副本。请记住 _.clone 是浅拷贝。如果您的其中一个项目本身就是一个对象引用,那么您最终将在每个孩子中获得相同的项目引用。
    【解决方案2】:

    items 当你将它添加到extend 调用时,使一个新的主干“类”成为类原型的一部分。

    由于 JavaScript 使用 Prototypal inheritance,这意味着该类的所有实例都可以使用它并共享。

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多