• 几种基于原型链的继承方式


    ECMASCript只支持实现继承,主要是依靠原型链来实现的。

    实现一个简单的原型链

    //SuperType类型
    function SuperType(){
      this.property = true;
    }
    SuperType.prototype.getSuperValue = function (){
      return this.property
    }
    //SubType类型
    function SubType(){
      this.subproperty = false;
    }
    // 重写了原型对象,SubType继承了SuperType
    SubType.prototype = new SuperType();
    SubType.prototype.getSubValue = function (){
      return this.subproperty;
    }
    let instance = new SubType();
    // 注意instance能使用SuperValue的方法
    console.log(instance.getSuperValue())//true

    所有引用类型默认继承了Object,而所有函数的默认原型都是Object的实例。

    console.log(instance instanceof Object);//true
    console.log(instance instanceof SuperType);//true
    console.log(instance instanceof SubType);//true

    也可以使用isPrototypeOf()方法

    console.log(Object.prototype.isPrototypeOf(instance));
    console.log(SuperType.prototype.isPrototypeOf(instance));
    console.log(SubType.prototype.isPrototypeOf(instance));

    注意通过原型链实现继承的时候,不要使用对象字面量创建原型方法。因为这样就会重写原型链,导致继承关系失效。

    原型链第一个问题就是原型链会导致继承的prototype的属性会“共享”,实例之间会相互影响,第二问题就是无法在不影响其他实例情况下给超类的构造函数传参。实际上很少单独使用原型链。

    1.组合继承

    function SuperType(name){
      this.name=name;
      this.color=['red','blue','green'];
    }
    SuperType.prototype.sayName = function (){
      console.log(this.name)
    }
    
    function SubType(name,age){
      //继承属性
      SuperType.call(this,name);
      this.age=age;
    }
    //继承方法
    SubType.prototype=new SuperType();
    SubType.prototype.constructor = SubType;
    SubType.prototype.sayAge = function (){
      console.log(this.age)
    };
    
    let instance1 = new SubType("nick", 29);
    instance1.color.push("black");
    console.log(instance1.color);
    instance1.sayName();
    instance1.sayAge();
    
    let instance2 = new SubType("grep", 27);
    console.log(instance2.color);
    instance2.sayName();
    instance2.sayAge();

    2.原型式继承

    // 对参数o进行一次浅复制
    function object(o){
      function F(){}
      F.prototype = o;
      return new F()
    }
    // 作为另一个对象的基础
    let person = {
      name:"nick",
      friends:['shellby','court','van']
    };
    let person2 = object(person);
    person2.name = 'grep';
    person2.friends.push("Rob");
    
    let person3 = object(person);
    person3.name = 'lina';
    person3.friends.push("Barbie");
    
    console.log(person.friends)//[ 'shellby', 'court', 'van', 'Rob', 'Barbie' ]

    person2和person3有着与person一样的共享属性

    ES5中使用Object.create来替代object方法,并且可以传入第二个参数,一个为新对象定义额外属性的对象。

    3.寄生式继承

    function createAnother(ori){
      // 创建一个新对象
      let clone = Object.create(ori);
      // 增强这个对象
      clone.sayHi = function (){
        console.log("hi")
      };
      return clone
    }
    let person = {
      name:"nick",
      friends:['shell','court','van']
    };
    let person1 = createAnother(person);
    person1.sayHi();
    

    4 寄生组合式继承

    组合继承的缺点就是会两次调用父类的构造函数,可以直接使用父类原型的复制副本。

    // 子类构造函数和父类构造函数
    function inheritPrototype(subType,superType){
      let prototype = Object.create(superType.prototype);
      prototype.constructor = subType;
      subType.prototype = prototype
    }
    function SuperType(name){
      this.name = name;
      this.colors = ['red', 'blue', 'green'];
    }
    SuperType.prototype.sayName = function (){
      console.log(this.name)
    }
    function SubType(name,age){
      SuperType.call(this,name)
      this.age = age
    }
    // 实际上就是复制父类的prototype方法
    inheritPrototype(SubType,SuperType);
    SubType.prototype.sayAge = function (){
      console.log(this.age)
    }
    let instance = new SubType('nick', '29')
    console.log(instance.colors,instance.name,instance.age)
    instance.sayAge()
    let instance2 = new SubType('grep', '27')
    console.log(instance2.colors,instance2.name,instance2.age)
    instance2.sayAge()

    这样只需要每次调用一次构造函数就行了。

  • 相关阅读:
    MOSS 之 自定义MembershipProvider实现Forms方式验证——学习实战篇
    (转)jquery.validate全攻略
    LinQ To Entity的增删改查(转)
    如何将程序集(.dll文件)添加到GAC(全局程序集缓存)?
    CSS Sprites (转)
    如何查看MOSS未知错误?
    用.Net开发Windows服务初探(转)
    早该知道的7个JavaScript技巧(转)
    最容易犯的13个JavaScript错误——转
    jQuery插件开发全解析(转)
  • 原文地址:https://www.cnblogs.com/haoqirui/p/13732989.html
Copyright © 2020-2023  润新知