zoukankan      html  css  js  c++  java
  • javascript的Mixins

    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

  • 相关阅读:
    iOS自己主动化測试的那些干货
    RecylerView 的使用方法
    java 获取局域网中的全部主机名和IP地址
    C++项目參考解答:求Fibonacci数列
    tableView的用法具体解释
    【jQuery小实例】---3 凤凰网首页图片动态效果
    【jQuery小实例】---2自定义动画
    【jQuery小实例】js 插件 查看图片
    【url重写】
    【文件上传】
  • 原文地址:https://www.cnblogs.com/sunshine-anycall/p/5605099.html
Copyright © 2011-2022 走看看