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

标签 javascript inheritance backbone.js mixins composition

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

在了解了组合(更像是 mix'n'match,即通过工厂)与继承(一种不灵活且模糊的耦合)相比的优势之后,我想知道如何实际利用这些知识,这使我Mixin pattern .

由于我主要在 Backbone 中进行开发,因此我创建了一个简单的 mixin 以在 View 中使用。实际上,我只是将基础 View 的一部分移到了 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
  }
});

现在使用Underscore的extend函数将getTemplate方法注入(inject)到MyView中,但这与继承BaseView<有什么不同,它还使用了 extend 调用 BaseView.extend 的不同实现?这还是 Backbone 中真正的继承吗?

最佳答案

编辑

我确信您在职业生涯中遇到过“合并”一词没有明确定义的情况。 “Mixin”在其他语言和概念中具有精确的含义,但在 Javascript 中,它具有与“merge”相同水平的精确性和良好定义,也就是说,不多。

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

mixin还有其他选择具有更奇特和有用的逻辑来处理合并键等中的冲突。 backbone.cocktail我记得是这样的。

如果您还没有看过extend从带注释的来源,请执行以下操作。

从带注释的源扩展

var 扩展 = 函数(protoProps, staticProps) { var 父级 = this; var child ;

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

The constructor function for the new subclass is either defined by you (the “constructor” property in your extend definition), or defaulted by us to simply call the parent constructor.

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

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

Add static properties to the constructor function, if supplied.

_.extend(child, parent, staticProps);

Set the prototype chain to inherit from parent, without calling parent‘s constructor function and add the prototype properties.

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

这是微妙非常重要。请注意,他们本来可以这样做:child.prototype = parent.prototype 。想想为什么他们没有这样做,以及这对你有什么好处。

顺便说一句,这两行是整个方法的核心,因为它 1) 为子级提供了自己的父级原型(prototype)副本,并为子级构造函数提供了原型(prototype)。因此,您得到的原型(prototype)对于 child 来说确实是独一无二的,但源自 parent 。

Set a convenience property in case the parent’s prototype is needed later.

    child.__super__ = parent.prototype;

    return child;
  };

下划线扩展怎么样?

下划线扩展是 merging 的一种方法。它是 Backbone.extend 流程的一部分但另一部分涉及实现inheritance .

现在是 mixin 库 cocktail对于 Backbone为您提供比 underscore 更智能的合并处理,因此如果您愿意 extending ,您可能想要寻求更多选择太多了。

https://github.com/onsi/cocktail

原版

嗯,我并不是声称完全实现了 diff比如说,extending之间来自哈希值和 mixin一个哈希,但我确实知道一些重要的事情。

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

var extend = function(protoProps, staticProps) {

有时我看到人们使用 mixin因为他们想要持续改变通过 staticProps 可以实现的目标.

第二,extend在语义上将扩展关联到 Clazz ... 100 次中有 99 次,您看不到 extend 的输入重复使用。

关于javascript - Backbone 中的 Mixin 模式 - 它与 Backbone 的扩展实现有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36389296/

相关文章:

java - 为什么java ArrayIndexOutOfBound Exception Extends IndexOutofBound Exception not Throwable?

node.js - Backbone.js 和 Node.js : Looking for a best practice for application settings

javascript - 检查 && 比较中的所有值?

java - 子类无法被保护

javascript - 访问内联 SVG

c# - 为不同数据库之间的共享功能创建通用/抽象 "DBContext"类

backbone.js - 错误回调总是被触发,即使它是成功的

javascript - 如何使用 Backbone.js 中的 set 方法更改默认模型属性

javascript - 单击按钮两次时防止警报显示两个弹出窗口

javascript - 如何捕捉剑道网格单元失焦事件?