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. 我的第一个WCF程序

    写WCF,VS需要一管理员身份呢启动,否则服务无法访问. model层 using System; using System.Runtime.Serialization; namespace MyMo ...

  2. input 原生上传文件(type = file)

    1.表单上传文件的步骤: - 1)设置enctype 默认为:enctype="application/x-www-form-urlencoded"(一般不设置) 若要表单中有需要 ...

  3. Vue 初始化多个Vue 及之间的相互修改

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. React-router4 第二篇url-params url参数

    官方文档 以下代码均来自于官方文档 上来一步走 import React from 'react' import { BrowserRouter as Router, Route, Link } fr ...

  5. MFC 一个无参线程的CreateThread 使用

    最近想把c#的一个工作中用到的软件用MFC 实现出来, 刚下手 要了解的东西挺多,不但要对c++的语法,大体看一遍. 还要看MFC 内一些窗体,之类的相关的定义,比如cpp ,.h 内的类的定义方式等 ...

  6. 解决IDEA 配置搞坏的问题

    如果我们把IDEA的配置给搞坏了,或者想重新配置,恢复到默认配置. 1.打开如下的目录(不同用户名目录有差异),如下所示: 2.删除掉config 和 system 目录,重新启动 IDEA会自动生成 ...

  7. 一个非常有意思的蜜罐T-Pot 16.10

    In March 2016 we released T-Pot 16.03 and the positive feedback encouraged us to continue developmen ...

  8. P<0.05就够了?还要校正!校正!3个方法献上

    P<0.05就够了?还要校正!校正!3个方法献上 (2017-01-03 17:55:12) 转载▼   分类: 数理统计 (转  医生科研助手 解螺旋 微信公众号)   当有多组数据要比较时, ...

  9. Windows服务器支持json文件

    Windows服务器默认是不支持json文件的直接读取的.如在浏览器中输入地址访问或是通过代码访问,都是无法获取到数据的.需要在服务器端进行配置,让服务器支持解析.json扩展名的json文件. 方法 ...

  10. visual studio 修改注释快捷键,和断点

    修改成alt+3和alt+4.效果不错 修改插入断点快捷键.这样按F12 就可以插入删除断点了.很爽 tab是批量加缩进 shift+tab 是批量减缩进