最近我一直在阅读有关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
的输入被重用。