javascript优化--08模式(代码复用)01

优先使用对象组合,而不是类继承;

类式继承:通过构造函数Child()来获取来自于另一个构造函数Parent()的属性;

  • 默认模式:子类的原型指向父类的一个实例
    function inherit(C, P) {
       C.prototype = new P();
    }
    
    function Parent(name) {
       this.name = name || 'Adam';
    }
    
    Parent.prototype.say = function () {
       return this.name;
    }
    
    function Child() {};
    
    inherit(Child, Parent);
    
    var kid = new Child();
    • 缺点:同时继承了两个对象的属性,效率低下;
  • 借用构造函数:之继承在父构造函数中添加到this的属性;
    function Parent(name) {
       this.name = name || 'Adam';
    }
    Parent.prototype.say = function () {
       return this.name;
    }
    function Child(name) {
       Parent.apply(this, arguments);
    }
    var kid = new Child();  //并没有继承到say方法
    • 多重继承:
      function Cat() {
      	this.legs = 4;
      	this.say = function () {
      		return 'meaoww';
      	}
      }
      function Bird() {
      	this.wings = 2;
      	this.fly = true;
      }
      function CatWings() {
      	Cat.apply(this);
      	Bird.apply(this);
      }
      var jane = new CatWings();
    • 优点:可以获取扶对象自身成员的真实副本,且不会有子对象覆盖父对象的问题;
  • 借用和设置原型:结合前两中模式,先借用构造函数,然后设置子构造函数的原型使其指向一个构造函数的实例;
    function Child(a, b, c, d) {
       Parent.apply(this, arguments);
    }
    Child.prototype = new Parent(); 

       缺点:父构造函数被调用两次;

  • 共享原型: 

    function inherit(C, P) {
        C.prototype = P.prototype;
    }
    

    即提供了简短迅速的原型链查询,也易导致影响其他对象;

  • 临时构造函数:解决共享原型的问题

    • 基本代码:

      function  inherit(C, P) {
      	var F = function () {};
      	F.prototype = P.prototype;
      	C.prototype = new F();
      }  
    •  存储超类:增加一个指向原始父对象的引用  

      function  inherit(C, P) {
      	var F = function () {};
      	F.prototype = P.prototype;
      	C.prototype = new F();
      	C.uber = P.prototype;
      } 
    • 重置构造函数:考虑可能会用到constructor

      function  inherit(C, P) {
      	var F = function () {};
      	F.prototype = P.prototype;
      	C.prototype = new F();
      	C.uber = P.prototype;
      	C.prototype.constructor = C;
      } 
    • 优化:避免每次需要继承时都创建

      var inherit = (function () {
      	var F = function () {};
      	return function (C, P) {
      		F.prototype = P.prototype;
      		C.prototype = new F();
      		C.uber = P.prototype;
      		C.prototype.constructor = C;
      	}
      })();
      
    • Klass: 模拟类的语法糖

      var klass = function (Parent, props) {
          var Child, F, i;
          //新构造函数
          Child = function () {
              if(Child.uber && Child.uber.hasOwnProperty('_construct')) {
                  Child.uber._construct.apply(this, arguments);
              }
              if(Child.prototype.hasOwnProperty('_construct')) {
                  Child.prototype._construct.apply(this, arguments);
              }
          }
          //继承
          Parent = Parent || Object;
          F = function() {};
          F.prototype = Parent.prototype;
          Child.prototype = new F();
          Child.uber = Parent.prototype;
          Child.prototype.constructor = Child;
          //添加实现方法
          for(i in props) {
              if(props.hasOwnProperty(i)) {
                  Child.prototype[i] = props[i];
              }
          }
          //返回该Class
          return Child;
      }
       
      var Man = klass(null/*父类*/, { /*新类的实现*/
          _construct: function (what) {
              console.log("Man's constructor");
              this.name = what;
          },
          getName: function () {
              return this.name;
          }
      });
       
      var first = new Man('Adam');
      first.getName();
       
      var SuperMan = klass(Man, {
          _construct: function (what) {
              console.log("SuperMan's constructor");
          },
          getName: function() {
              var name = SuperMan.uber.getName.call(this);
              return "I am " + name;
          }
      });
       
      var clark = new SuperMan('Clark kent');
      clark.getName();
       
      console.log(clark instanceof Man);
      console.log(clark instanceof SuperMan);
      

        

      最好避免使用;适用于对类熟悉,对原型不熟的情况;  

       

原文地址:https://www.cnblogs.com/jinkspeng/p/4158373.html