JavsScript继承

原型链继承

原型链基本概念:通俗的说 就是一个子对象的原型对象又指向它自己的原型对象,而这个原型对象又指向它的原型对象,一直到object

原型继承实现:

<script>
   function SuperType(){
       this.property=true;
   }
   SuperType.prototype.getSuperValue=function () {
       return this.property;
   }
   
   function SubType() {
       this.subproperty=false;
   }
   
   SubType.prototype=new SuperType();
   SubType.prototype.getSubValue=function () {
       return this.subproperty;
   }
   var instance=new SubType();
   console.log(instance.getSuperValue());
</script>

本质:重写原型对象,把原型对象等于另一个类型的实例,给它换一个新原型.

console.log(instance);

更清晰地了解原型链
JavsScript继承
这里instance指向SubType的原型,SubType的原型又指向SuperType的原型,SuperType的原型指向Object,getSuperValue()在SuperType.prototype中,而getSubValue()在SubType.prototype中,也就是SuperType中.

注意:在通过原型链实现继承时,不能使用字面量创建原型方法,也就是不能通过字面量往里面添加原型方法,这样会重写原型链.

<script>
   function SuperType(){
       this.property=true;
   }
   SuperType.prototype.getSuperValue=function () {
       return this.property;
   }
   function SubType() {
       this.subproperty=false;
   }
   
   SubType.prototype=new SuperType();
   //使用字面量添加新方法会使上一行无效
   SubType.prototype={
       getSubValue:function () {
           return this.subproperty;
       },
       someOtherMethod:function () {
           return false;
       }
   };
   
    var instance=new SubType();
   console.log(instance.getSuperValue());//error
</script>

缺点:
用原型链实现继承,所初始化的实例都会公用一个同一个属性,所以很少使用

<script>
   function SuperType(){
       this.color=["red","blue","yellow"];
   }
   function SubType() {
       //this.subproperty=false;
   }
   
   SubType.prototype=new SuperType();
   
   stance1=new SubType();
   instance1.color.push("black");
   console.log(instance1.color);//"red","blue","yellow","black"

   var instance2=new SubType();
   console.log(instance2.color);//"red","blue","yellow","black"
</script>

借用构造函数

实现:

<script>
   function SuperType(){
       this.color=["red","blue","yellow"];
   }

   function SubType() {
      SuperType.call(this);
   }
   SubType.prototype=new SuperType();

   var instance1=new SubType();
   instance1.color.push("black");
   console.log(instance1.color);//"red","blue","yellow","black"

   var instance2=new SubType();
   console.log(instance2.color);//"red","blue","yellow"
</script>

本质:在子类型构造函数的内部调用超类型构造函数,通过call或者apply改变父类的this
通俗的说就是在新的SubType对象上执行SuperType()函数中定义的所有对象初始化代码,所以SubType的每个实例都会具有自己的color属性副本.

可以传递参数

<script src="../JS/jquery 1.12.4.js"></script>
 <script>
    function SuperType(name) {
        this.name=name;
    }
    function SubType() {
        SuperType.call(this,"wsp");
        this.age=22;
    }
    var instance=new SubType();
    console.log(instance.name);//wsp
    console.log(instance.age);//22
 </script>

缺点:方法都在构造函数中调用,无法进行函数复用,所以也很少单独使用.

组合继承

将原型链继承和借用构造函数组合到一块.最常用的继承模式

实现:

<script>
   function SuperType(name) {
       this.name=name;
       this.color=["red","blue","yellow"];
   }
   SuperType.prototype.sayName=function () {
       alert(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 () {
     alert(this.age);  
   };
   
   
   var instance=new SubType("wsp",22);
   instance.color.push("black");
   console.log(instance.color);//"red","blue","yellow","black"
   instance.sayAge();//22
   instance.sayName();//wsp

   var instance2=new SubType("thh",20);
   console.log(instance2.color);//"red","blue","yellow"
   instance2.sayAge();//20
   instance2.sayName();//thh
</script>

原型式继承

实现:

<script>
  function  object(o) {
      function F() {}
      F.prototype=o;
      return new F();
  }
  var Person={
      name:"wsp",
      friend:["thh","hhp","hhh"]
  }
  
  var anotherPerson=Object(Person);
  anotherPerson.name="Greg";
  anotherPerson.friend.push("Rob");

  var yetotherPerson=Object(Person);
  yetotherPerson.name="Linda";
  yetotherPerson.friend.push("Bob");
  
  console.log(Person.friend);//"thh","hhp","hhh","Rob","Bob"
</script>

本质:object将传人进去的对象执行了一次浅复制,这种继承方式要求必须有一个对象作为另一个对象的基础(也可以说是你要创建的对象),然后传递给object,再根据需要进行修改.
这个例子中,Person就是那个基础对象,传入object中返回一个新对象,这个新对象将Person作为原型,原型里的属性被共享.

后来新增Object.create()方法规范了原型式继承
可传递二个参数,第二个参数可选

<script>
  
  var Person={
      name:"wsp",
      friend:["thh","hhp","hhh"]
  }
  
  //传递一个参数与object方法行为相同
  var anotherPerson=Object.create(Person);
  anotherPerson.name="Greg";
  anotherPerson.friend.push("Rob");

  var yetotherPerson=Object.create(Person);
  yetotherPerson.name="Linda";
  yetotherPerson.friend.push("Bob");

  console.log(Person.friend);//"thh","hhp","hhh","Rob","Bob"
</script>
<script>

  var Person={
      name:"wsp",
      friend:["thh","hhp","hhh"]
  }
  //传递二个参数会增加或覆盖同名属性
  var anotherPerson=Object.create(Person,{name:{value:"hhh"}});
  console.log(anotherPerson.friend);//"hhh"
</script>

寄生式继承

<script>
  function  object(o) {
      function F() {}
      F.prototype=o;
      return new F();
  }
  
  function createAnother(original){
      var clone=object(original);//通过调用函数构造一个新对象
      clone.sayHi=function () {
          alert("hi");           //以某种方式增强这个对象
      };
      return clone;
  }

  var Person={
      name:"wsp",
      friend:["thh","hhp","hhh"]
  }
  
  var anotherPerson=createAnother(person);
  anotherPerson.sayHi();//hi
</script>

本质:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式增强对象,在这里的object对象不是必须的,任何能返回新对象的函数都适用于此模式.

科比走好,愿天堂也有篮球

JavsScript继承JavsScript继承 睡什么觉,起来打代码 发布了4 篇原创文章 · 获赞 4 · 访问量 2898 私信 关注
上一篇:第5章 技巧性基础:5.1 关键字typename


下一篇:java – 在什么方面子类型与使用中的子类不同?