mixin在javascript里可以看作是一种从别的对象"借用"功能的方法。每一个新定义的对象都有一个 prototype属性,其他的对象就可以从这里"借用"功能。这里的功能可以是一个属性,也可以是一个方法。

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.jsextend()方法:

// 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

javascript的Mixins的更多相关文章

  1. JavaScript mixins

    mixin 是一个类,该类的方法被添加,混合进另外一个类.一个基础类会包含mixin类的方法而不是继承它.这样你就可以使用不同的mixin类来增加或者增强基础类的功能. 这编内容包含怎么样使用java ...

  2. JavaScript Patterns 6.6 Mix-ins

    Loop through arguments and copy every property of every object passed to the function. And the resul ...

  3. JavaScript面向对象之我见

    序言 在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式.对于为什么要模拟类语言的面向对象,我个人认为:某些 ...

  4. ES6新特性:使用新方法定义javascript的Class

    ES6中定义类的方式, 就是ES3和ES5中定义类的语法糖,虽然也有些区别,但是整体定义类的方式更加简洁,类的继承更加方便, 如果想对ES6中的继承更加熟悉, 最好了解ES5中原型继承的方式, 博客园 ...

  5. TypeScript & JavaScript

    http://www.typescriptlang.org/docs/tutorial.html handbook: Basic Types Variable Declarations Interfa ...

  6. a primary example for Functional programming in javascript

    background In pursuit of a real-world application, let’s say we need an e-commerce web applicationfo ...

  7. EXTJS4自学手册——EXT基本方法、属性(mixins多继承、statics、require)

    1.mixins 说明:类似于面向对象中的多继承 <script type="text/javascript"> Ext.onReady(function () {// ...

  8. Javascript.ReactNative-2-javascript-syntax-in-react-native

    JavaScript Syntax in React Native Contents: Arrow Function Let+Const Default + Rest + Spread Destruc ...

  9. 大型 JavaScript 应用架构中的模式

    原文:Patterns For Large-Scale JavaScript Application Architecture by @Addy Osmani 今天我们要讨论大型 JavaScript ...

随机推荐

  1. mysql 复制原理与实践

    复制功能是将一个mysql数据库上的数据复到一个或多个mysql从数据库上. 复制的原理:在主服务器上执行的所有DDL和DML语句都会被记录到二进制日志中,这些日志由连接到它的从服务器获取,并复制到从 ...

  2. Liunx rm

    rm是一个危险的命令,使用的时候要特别当心,尤其对于新手,否则整个系统就会毁在这个命令(比如在/(根目录)下执行rm * -rf,这是一个危险的动作,“ * ”代表任意个字符).所以,我们在执行rm之 ...

  3. Window10系统的安装

    关于系统的安装网上有许多的教程,本文的教程并没有什么特别的.只是将自己在安装过程中遇到的问题记录下来,方便以后观看. 1.下载系统镜像 首先从MSDN上下载windows10镜像.在操作系统Windo ...

  4. Eigen解线性方程组

    一. 矩阵分解: 矩阵分解 (decomposition, factorization)是将矩阵拆解为数个矩阵的乘积,可分为三角分解.满秩分解.QR分解.Jordan分解和SVD(奇异值)分解等,常见 ...

  5. angular2.0学习笔记3.了解angular2.0项目结构

    1.我们应用的代码都位于src文件中,包括所有的组件.模板.样式.图片以及我们的应用所需的任何东西都在这个文件来里. 2.src这个文件夹之外的文件都是为构建应用提供支持用的. src文件夹及用途说明 ...

  6. H5C3动画

    1 渐变 /* 渐变:不同颜色之间的柔和过渡 线性渐变:沿着某条直线发生渐变效果 注意:渐变准备来说是一张背景图 语法:linear-gradient */ background-image: lin ...

  7. Linux vps服务器国产面板wdcp的安装和使用方法

    对于大多数站长来说,稳定的服务器不可或缺,这是我做网站以来的深刻体会,因为之前我在网站运营方面因这个原因吃了很多亏.在这里说出,只希望朋友们不要像我一样.在网站优化过程中,服务器因素导致排名下滑,甚至 ...

  8. PID参数调节口诀

    参数整定找最佳, 从小到大顺序查. 先是比例后积分, 最后再把微分加. 曲线振荡很频繁, 比例度盘要放大. 曲线漂浮绕大弯, 比例度盘往小扳. 曲线偏离回复慢, 积分时间往下降. 曲线波动周期长, 积 ...

  9. 可读性很强的C语言的函数指针定义

    通常C/C++程序里面要用到大量的指针,其语法非常难以阅读.比如下面的vp指针类型: #include <iostream> using namespace std; typedef vo ...

  10. 通过代理上网时,qq等应用程序连网出错

    虽然现在基本上都用无线,有线宽带等,但是有时候还是避免不了通过代理上网时,于是就发生浏览器可以正常浏览网页,qq等应用程序连接出错等问题,上网搜了好长时间,    都没解决问题,后来慢慢琢磨(其实是乱 ...