如何在Javascript中正确使用mixins
我正在组织一个小企业应用程序,但希望尽可能干。 结果,我一直在看mixin库。
我遇到了这个库,并认为这可能是一个很好的select,因为它允许你在运行时混合进出。 另外,我可以只有一个基类(BaseView),例如只是混入。
问题
- 什么是有用的Mixin的一些真正的应用程序示例? (不要再有抽象的例子)
- 我甚至需要扩展类,或者我可以使用这个库来pipe理所有的扩展和混合?
另请参阅:
- 在javascript中的性状
- stackoverflow.com :: Javascript特征模式资源
如果涉及到像Mixins和Traits这样基于JavaScript和基于angular色的组合方法,那么我同时非常有见地。 我总是会指出图书馆不可知论的两种纯粹基于function的模式组合 – 首先是模块模式,其次是“飞行混合”模式,因为它已被重新发现,2011年5月由Angus Croll命名和描述。但是我也会推荐阅读从2014年4月开始的一篇论文。
- JavaScript Mixins重新审视
- 用于推广面向angular色编程方法(如Traits和Mixins)的JavaScript有很多才能
问题
- 1)什么是有用的Mixins的一些真正的应用实例? (不要再有抽象的例子)
- 2)我是否甚至需要扩展类,或者我可以使用这个库来pipe理所有扩展和混合?
回答你的两个问题
1) [Observable]
可能是Mixins最常见的现实世界的例子之一。 但是这不是提供完整代码库的正确地方。 Smart Talents章节中不断增长的例子确实提供了一个[Queue]
工厂的工作实现,它在开始时只是使用不同的Mixins,如[Enumerable]
和[Allocable]
但最后也适用已经提到的[Observable]
。
第二)只需使用您select或需要的模块系统 – CommonJS或AMD 。 你的工厂模块,甚至实例/对象,然后通过委托检索额外的行为; 因此他们积极地call
/ apply
Mixin或Trait模块。
最后 – 缩短的示例代码:
var Observable_SignalsAndSlots = (function () { var Event = function (target, type) { this.target = target; this.type = type; }, EventListener = function (target, type, handler) { var defaultEvent = new Event(target, type); this.handleEvent = function (evt) { /* ... */ }; this.getType = function () { return type; }; this.getHandler = function () { return handler; }; }, EventTargetMixin = function () { var eventMap = {}; this.addEventListener = function (type, handler) { /* ... */ }; this.dispatchEvent = function (evt) { /* ... */ }; } ; return EventTargetMixin; }).call(null); var Queue = (function () { var global = this, Observable = global.Observable_SignalsAndSlots, //Allocable = global.Allocable, Queue, onEnqueue = function (queue, type) { queue.dispatchEvent({type: "enqueue", item: type}); }, onDequeue = function (queue, type) { queue.dispatchEvent({type: "dequeue", item: type}); }, onEmpty = function (queue) { queue.dispatchEvent("empty"); } ; Queue = function () { // implementing the [Queue] Constructor. var queue = this, list = [] ; queue.enqueue = function (type) { list.push(type); onEnqueue(queue, type); return type; }; queue.dequeue = function () { var type = list.shift(); onDequeue(queue, type); (list.length || onEmpty(queue)); return type; }; Observable.call(queue); //Allocable.call(queue, list); }; return Queue; }).call(null); var q = new Queue; q.addEventListener("enqueue", function (evt) {console.log("enqueue", evt);}); q.addEventListener("dequeue", function (evt) {console.log("dequeue", evt);}); q.addEventListener("empty", function (evt) {console.log("empty", evt);}); console.log("q.addEventListener : ", q.addEventListener); console.log("q.dispatchEvent : ", q.dispatchEvent); console.log("q.enqueue('the') ... ", q.enqueue('the')); // "enqueue" Object {type: "enqueue", item: "the", target: Queue} console.log("q.enqueue('quick') ... ", q.enqueue('quick')); // "enqueue" Object {type: "enqueue", item: "quick", target: Queue} console.log("q.enqueue('brown') ... ", q.enqueue('brown')); // "enqueue" Object {type: "enqueue", item: "brown", target: Queue} console.log("q.enqueue('fox') ... ", q.enqueue('fox')); // "enqueue" Object {type: "enqueue", item: "fox", target: Queue} console.log("q.dequeue() ... ", q.dequeue()); // "dequeue" Object {type: "dequeue", item: "the", target: Queue} console.log("q.dequeue() ... ", q.dequeue()); // "dequeue" Object {type: "dequeue", item: "quick", target: Queue} console.log("q.dequeue() ... ", q.dequeue()); // "dequeue" Object {type: "dequeue", item: "brown", target: Queue} console.log("q.dequeue() ... ", q.dequeue()); // "dequeue" Object {type: "dequeue", item: "fox", target: Queue} // "empty" Object {target: Queue, type: "empty"} console.log("q.dequeue() ... ", q.dequeue()); // "dequeue" Object {type: "dequeue", item: undefined, target: Queue} // "empty" Object {target: Queue, type: "empty"}
.as-console-wrapper { max-height: 100%!important; top: 0; }
mixin只是一个不同的概念,关于如何组织代码和inheritance。 你当然可以把它与经典或原型inheritance结合起来,但它也可以独立工作,可以这么说。
例如,我们不是创build“委托”对象属性/查找(如原型inheritance ),而是从多个其他对象中真正“ 形成 ”新的独立对象。 这也被称为“ 多重inheritance ”,单靠Javascript的原型inheritance不能轻易实现。
举个例子:
var pianist = { play: function() {} }; var programmner: { code: function() {} };
现在我们可以创build另一个对象了
var Jim = Object.create( null ); // create a fully self-defining object extend( Jim, pianist ); extend( Jim, programmer );
这个伪extend
方法看起来像(ES5):
function extend( target, source ) { Object.getOwnPropertyNames( source ).forEach(function( key ) { Object.defineProperty( target, key, Object.getOwnPropertyDescriptor(source, key)) }); return target }
我其实没有正确回答你的问题,但是我觉得你的问题没有真正的答案。 它就像你要使用它一样真实,没有“应用程序特定的”用例。
我们使用一个名为鸡尾酒的mixin库(mixin …得到它?)。 它专门用于Backbone应用程序,但相当不错。
我们已经撰写了关于我们的使用模式的细节,这些使用模式比我在这里描述的做得更好。