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

时间:2016-04-03 18:20:21

标签: javascript inheritance backbone.js mixins composition

最近我一直在阅读JavaScript模式和架构。我经常遇到的一个提示是赞成组合优于继承,所以我花了一天时间深入研究这个问题。

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

由于我主要在Backbone中开发,因此我在视图中创建了一个简单的mixin。实际上,我只是将baseview的一部分移动到了mixin中:

在:

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
  }
});

后:

getTemplate

现在使用Underscore的MyView函数将extend方法注入BaseView,但这与继承自extend的方式有何不同,后者也使用了不同的实现方式BaseView.extend来电public static void main(String[] args) { Scanner Read = new Scanner(System.in); int n; int v; System.out.println("Please enter an equation"); try { n = Read.nextInt(); } catch (InputMismatchException ex) { System.out.println("Bad input, please correct your first operand."); return; } char operands; operands = Read.next().charAt(0); //reading up till the next space and pulling the first character it read try { v = Read.nextInt(); } catch (InputMismatchException ex) { System.out.println("Bad input, please correct your second operand."); return; } if (operands == '+') System.out.println(n + "+" + v + "=" + addition(n, v)); if (operands == '-') System.out.println(n + "-" + v + "=" + subtraction(n, v)); if (operands == '*') System.out.println(n + "*" + v + "=" + multiply(n, v)); if (operands == '/') System.out.println(n + "/" + v + "=" + division(n, v)); } public static int addition(int n, int v) { return n + v; } public static int subtraction(int n, int v) { return n - v; } public static int multiply(int n, int v) { return n * v; } public static int division(int n, int v) { return n / v; } ?这是Backbone中的真正继承吗?

1 个答案:

答案 0 :(得分:2)

修改

我确定你在职业生涯中遇到过“" merge"没有明确的定义。 "密新"在其他语言和概念中具有精确的含义,但在Javascript中,它具有相同的精度和良好的定义,以及" merge"是的,也就是说,并不多。

您指出在两个实例中都得到_.extend的结果是正确的。这是您特定选择mixin实施的结果......在_.extend中调用initialize

mixin还有其他选择,它们具有更多奇特且有用的逻辑,用于处理合并键中的冲突等。 backbone.cocktail是我记得的。

如果您没有从带注释的来源查看extend,请在下面进行操作。

从带注释的源

扩展

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

我们从功能extend&#39签名...

开始
  

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

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;
  };

下划线扩展怎么样?

下划线扩展是merging的一种方法。它是Backbone.extend过程的一部分,但另一部分与实现inheritance有关。

现在,cocktail的mixin库Backbone为您提供了比underscore更智能的合并处理,因此如果您想extending,可能需要寻求更多选项太过分了。

https://github.com/onsi/cocktail

原稿

好吧,我并没有声称完全实现diff之间的extending,例如mixin来自散列和extend散列,但我确实知道一些重要的事情。

首先,var extend = function(protoProps, staticProps) { 需要第二个参数:) 很多人都不知道。

mixin

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

其次,Clazz在语义上将扩展名与extend ...相关联... 99次中的100次,您没有看到function displayFormInput() { var formElements = document.forms["inputForm"].getElementsByTagName("input"); var elements = document.getElementsByClassName('display'); for (var i; i < elements.length; i++) { elements[i].innerHTML += formElements[i].value; alert(i); // never gets called } } 重复使用的输入。