zoukankan      html  css  js  c++  java
  • javascript继承扩展类方法实现

    javascript没有原生的继承语法,这确实很让人困惑,但是广大人民群从的智慧是无穷的。最近呢,正尝到一点从源码中学习的甜头,不分享一下实在难以平复激动的心情。前不久改造视频播放插件的时候,找到了videojs这个优秀的开源项目。经过一段时间深入学习它的源码,发现它的继承机制写的很好,而且短小精悍,于是决定把它拔离出来,做成一个单独的库,方便以后项目中使用。

        

    复制代码
    //定义一个命名空间 
    var xut = {};
    
    /**
     * Core Object/Class for objects that use inheritance + contstructors
     *
     * @class
     * @constructor
     */
    xut.CoreObject = xut['CoreObject'] = function(){};
    
    /**
     * Create a new object that inherits from this Object
     *
     *     var Animal = CoreObject.extend();
     *     var Horse = Animal.extend();
     *
     * @param {Object} props Functions and properties to be applied to the
     *                       new object's prototype
     * @return {xut.CoreObject} An object that inherits from CoreObject
     * @this {*}
     */
    xut.CoreObject.extend = function(props){
      var init, subObj;
    
      props = props || {};
      // Set up the constructor using the supplied init method
      // or using the init of the parent object
      // Make sure to check the unobfuscated version for external libs
      init = props['init'] || props.init || this.prototype['init'] || this.prototype.init || function(){};
      // In Resig's simple class inheritance (previously used) the constructor
      //  is a function that calls `this.init.apply(arguments)`
      // However that would prevent us from using `ParentObject.call(this);`
      //  in a Child constuctor because the `this` in `this.init`
      //  would still refer to the Child and cause an inifinite loop.
      // We would instead have to do
      //    `ParentObject.prototype.init.apply(this, argumnents);`
      //  Bleh. We're not creating a _super() function, so it's good to keep
      //  the parent constructor reference simple.
      subObj = function(){
        init.apply(this, arguments);
      };
    
      // Inherit from this object's prototype
      subObj.prototype = xut.obj.create(this.prototype);
      // Reset the constructor property for subObj otherwise
      // instances of subObj would have the constructor of the parent Object
      subObj.prototype.constructor = subObj;
    
      // Make the class extendable
      subObj.extend = xut.CoreObject.extend;
      // Make a function for creating instances
      subObj.create = xut.CoreObject.create;
    
      // Extend subObj's prototype with functions and other properties from props
      for (var name in props) {
        if (props.hasOwnProperty(name)) {
          subObj.prototype[name] = props[name];
        }
      }
    
      return subObj;
    };
    
    xut.obj = {};
    
    xut.obj.create = Object.create || function(obj){
      //Create a new function called 'F' which is just an empty object.
      function F() {}
    
      //the prototype of the 'F' function should point to the
      //parameter of the anonymous function.
      F.prototype = obj;
    
      //create a new constructor function based off of the 'F' function.
      return new F();
    };
    
    /**
     * Create a new instace of this Object class
     *
     *     var myAnimal = Animal.create();
     *
     * @return {xut.CoreObject} An instance of a CoreObject subclass
     * @this {*}
     */
    xut.CoreObject.create = function(){
      // Create a new object that inherits from this object's prototype
      var inst = xut.obj.create(this.prototype);
    
      // Apply this constructor function to the new object
      this.apply(inst, arguments);
    
      // Return the new object
      return inst;
    }; 
    复制代码

    项目地址:https://github.com/bjtqti/mini-extend

    关于它的使用,我会抽空在git上详细说明,先作一个简单的案例,有兴趣的读者可以自行分析一下它的妙处:

    复制代码
    var Animal = xut.CoreObject.extend({
        init : function(name){
            this.name = name;
        }
    });
    
    Animal.prototype.getName = function(){
        return this.name;
    }
    
    Animal.prototype.makeSound = function(){
        alert('xxx');
    }
    
    var Bird = Animal.extend();
    
    var Dog = Animal.extend({
        makeSound : function(){
            alert('wang...')
        }
    });
    
    var b = new Bird('bage');
    var d = new Dog('wang');
    d.makeSound()
    
    b.makeSound()
    复制代码

    子类可以很方便的继承父类的功能,而且子类也可以很自由的修改父类的功能,还不会影响它子类。这对于熟悉php/java等语言的程序员来说,这简直就是废话,但是js用这一百来行的代码实现,做到这种程度,非常的不容易。

  • 相关阅读:
    TF.VARIABLE和TENSOR的区别(转)
    同步与异步,阻塞与非阻塞的区别
    tensorflow op tf.global_variables_initializer
    iOS viewDidUnload方法
    Objective-C中的@property和@synthesize用法
    UIDatePicker的时间选择器里的时区的问题
    IOS 小技巧积累
    IOS atomic与nonatomic,assign,copy与retain的定义和区别
    XCODE4.6从零开始添加视图
    Xcode无法设置视图的 autosizing control原因
  • 原文地址:https://www.cnblogs.com/sunshq/p/4210270.html
Copyright © 2011-2022 走看看