Backbone 中的 Mixin 模式 - 它与 Backbone 的扩展实现有何不同?



最近我一直在阅读有关JavaScript模式和架构的一般知识。我经常遇到的一个技巧是喜欢组合而不是继承,所以我花了一天的时间对此进行了深入的研究。

在理解了组合(更像是混合‘匹配,即通过工厂)与继承(一种不灵活和模糊的耦合)相比的优势后,我想知道如何实际利用这些知识,这让我想到了Mixin模式。

由于我主要在Backbone中开发,所以我创建了一个简单的mixin来在视图中使用。事实上,我只是将基本视图的一部分移动到了一个mixin:中

之前:

var BaseView = Backbone.View.extend({
  getTemplate: function () {
    return template;
  }
});
var MyView = BaseView.extend({
  template: 'dummy',      
  initialize: function () {
    // Do stuff
  },
  render: function () {
    // Do render stuff
  }
});

之后:

var myMixin = {
  getTemplate: function () {
    return template;
  }
};
var MyView = Backbone.View.extend({
  template: 'dummy'
  initialize: function () {
    _.extend(this, myMixin)
    // Do stuff
  },
  render: function () {
    // Do render stuff
  }
});

现在,使用Undercore的extend函数将getTemplate方法注入到MyView中,但这与继承BaseView有什么不同,后者也使用了extend调用BaseView.extend的不同实现?这是Backbone真正的继承吗?

编辑

我相信你在职业生涯中遇到过"合并"一词定义不明确的例子。"Mixin"在其他语言和概念中有着精确的含义,但在Javascript中,它具有与"merge"相同的精度和良好的定义,也就是说,不多。

您正确地指出,在这两种情况下,您都会得到_.extend的结果。这是您特别选择mixin实现的结果。。。即在CCD_ 10中调用CCD_。

mixin还有其他选择,它们有更奇特、更有用的逻辑来处理合并密钥中的冲突等等。我记得backbone.cocktail

如果您还没有从注释源中查看extend,请执行以下操作。

从带注释的源扩展

var extend=函数(protoProps,staticProps){var parent=this;var child;

我们从函数extend的签名开始。。。

新子类的构造函数由您定义(扩展定义中的"构造函数"属性),或默认值通过我们简单地调用父构造函数。

if (protoProps && _.has(protoProps, 'constructor')) {
  child = protoProps.constructor;
} else {
  child = function(){ return parent.apply(this, arguments); };
}

换句话说,要么我们已经有了孩子的构造函数,要么我们没有,在这种情况下,它会得到父母。

向构造函数添加静态属性(如果提供)。

_.extend(child, parent, staticProps);

将原型链设置为从父级继承,而不调用parent的构造函数,并添加原型属性。

child.prototype = _.create(parent.prototype, protoProps);
child.prototype.constructor = child;

这是微妙的,但非常重要。请注意,他们本可以做到:child.prototype = parent.prototype。想想他们为什么不这样做,以及这对你有什么影响。

顺便说一句,这两条线是整个方法的核心,因为它1)给孩子自己的父母原型的副本,并给原型孩子的构造函数。因此,你得到了一个原型,它对孩子来说是真正独特的,但却是从父母那里延伸出来的。

设置一个方便属性,以备需要父对象的原型时使用后来

    child.__super__ = parent.prototype;
    return child;
  };

下划线扩展怎么办

核下扩展是CCD_ 16的一种方法。这是Backbone.extend过程的一部分,但另一部分涉及实现inheritance

现在,Backbone的混合库cocktail为您提供了比underscore更智能的合并处理,因此,如果您觉得extending太多,您可能需要寻求进一步的选项。

https://github.com/onsi/cocktail

Orig

好吧,我并没有声称完全实现diff,比如说,extending来自哈希,mixin来自哈希,但我确实知道一些重要的事情。

首先,extend采用第二个参数:)很多人不知道。

var extend = function(protoProps, staticProps) {

有时我看到人们使用mixin,因为他们想不断地改变通过staticProps可以实现的目标。

其次,extend在语义上将扩展与Clazz相关联。。。100次中有99次,您看不到对extend的输入被重用。

最新更新