最近我一直在阅读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中的真正继承吗?
答案 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
}
}
重复使用的输入。