javascript的Mixins
2016-06-21 21:33
375 查看
mixin在javascript里可以看作是一种从别的对象"借用"功能的方法。每一个新定义的对象都有一个 prototype属性,其他的对象就可以从这里"借用"功能。这里的功能可以是一个属性,也可以是一个方法。
mixins这种借用在 javascript里非常的适用。在重用代码的时候可以使用mixins来实现继承,也可以达到类似多继承的效果。假设我们定义了这么一个对象:
我们可以非常容易的使用一个helper来扩展现有的对象。比如使用
从代码可以看到,这个mixins实现的非常简单。在下一个例子中我们会使用两个构造函数:一个
这里例子会非常清楚的展示argument方法是怎么达到"借用"效果的:
但是,mixins也有值得商榷的一面。有很多开发者认为把方法注入到其他的对象里不是很好,这样会造成prototype污染,也会造成我们本来定义的对象的不确定性。这些确实会发生。
我个人觉得良好的文档会减少mixins的使用造成的困惑。而且,不管任何的模式。只要我们在开发的时候就考虑好它的利和弊,那么就会减少不必要的问题。
原文地址:https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch09s13.html
mixins这种借用在 javascript里非常的适用。在重用代码的时候可以使用mixins来实现继承,也可以达到类似多继承的效果。假设我们定义了这么一个对象:
var myMixins = { moveUp: function(){ console.log( "move up" ); }, moveDown: function(){ console.log( "move down" ); }, stop: function(){ console.log( "stop! in the name of love!" ); } };
我们可以非常容易的使用一个helper来扩展现有的对象。比如使用
Underscore.js的
extend()方法:
// A skeleton carAnimator constructor function carAnimator(){ this.moveLeft = function(){ console.log( "move left" ); }; } // A skeleton personAnimator constructor function personAnimator(){ this.moveRandomly = function(){ /*..*/ }; } // Extend both constructors with our Mixin _.extend( carAnimator.prototype, myMixins ); _.extend( personAnimator.prototype, myMixins ); // Create a new instance of carAnimator var myAnimator = new carAnimator(); myAnimator.moveLeft(); myAnimator.moveDown(); myAnimator.stop(); // Outputs: // move left // move down // stop! in the name of love!
从代码可以看到,这个mixins实现的非常简单。在下一个例子中我们会使用两个构造函数:一个
Car,一个
Mixin。我们要做的就是使用一个自定义的argument方法来扩展Car,这样
Car可以从
Mixin里"借用"某些特定的方法。比如,
driveForward()和
driveBackword()。这次我们不使用
Underscore.js。
这里例子会非常清楚的展示argument方法是怎么达到"借用"效果的:
// Define a simple Car constructor var Car = function ( settings ) { this.model = settings.model || "no model provided"; this.color = settings.color || "no colour provided"; }; // Mixin var Mixin = function () {}; Mixin.prototype = { driveForward: function () { console.log( "drive forward" ); }, driveBackward: function () { console.log( "drive backward" ); }, driveSideways: function () { console.log( "drive sideways" ); } }; // Extend an existing object with a method from another function augment( receivingClass, givingClass ) { // only provide certain methods if ( arguments[2] ) { for ( var i = 2, len = arguments.length; i < len; i++ ) { receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } } // provide all methods else { for ( var methodName in givingClass.prototype ) { // check to make sure the receiving class doesn't // have a method of the same name as the one currently // being processed if ( !Object.hasOwnProperty(receivingClass.prototype, methodName) ) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } // Alternatively: // if ( !receivingClass.prototype[methodName] ) { // receivingClass.prototype[methodName] = givingClass.prototype[methodName]; // } } } } // Augment the Car constructor to include "driveForward" and "driveBackward" augment( Car, Mixin, "driveForward", "driveBackward" ); // Create a new Car var myCar = new Car({ model: "Ford Escort", color: "blue" }); // Test to make sure we now have access to the methods myCar.driveForward(); myCar.driveBackward(); // Outputs: // drive forward // drive backward // We can also augment Car to include all functions from our mixin // by not explicitly listing a selection of them augment( Car, Mixin ); var mySportsCar = new Car({ model: "Porsche", color: "red" }); mySportsCar.driveSideways(); // Outputs: // drive sideways
好处和坏处
Mixins可以减少代码的重复增加代码的复用。如果一个对象需要使用其他对象已经定义的"功能"的时候,我们就可以使用mixins复用代码。这样就可以集中精力实现那么独一无二,确实非常需要的代码上。但是,mixins也有值得商榷的一面。有很多开发者认为把方法注入到其他的对象里不是很好,这样会造成prototype污染,也会造成我们本来定义的对象的不确定性。这些确实会发生。
我个人觉得良好的文档会减少mixins的使用造成的困惑。而且,不管任何的模式。只要我们在开发的时候就考虑好它的利和弊,那么就会减少不必要的问题。
原文地址:https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch09s13.html
相关文章推荐
- js获取项目路径
- C#解析Json数据(利用Newtonsoft.Json库)
- JavaScript基础教程(二)
- 简单理解jsonp原理
- 说说JSON和JSONP
- json解析utils
- JS点击标题自动排序
- JavaScript基础教程(一)
- js常见坑
- javascript的Mixins
- 【JS】DOM与BOM
- jsp和servlet中文乱码
- angular Jsonp的坑
- 动态加载js文件默认为异步请求的问题解决
- JavaScript父子窗口互传数据
- JS 获取浏览器窗口大小
- jsp理论基础
- jsp、Html页面注释的种类
- 【Leafletjs】7.结合echart图表展示信息
- js中时间的大小比较,留着备用!