javascript特征之:继承

继承可以解决代码复用,让编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。
JS中实现继承的方式

1.对象冒充

<html>
  <head>
    <script type="text/javascript">
      //定义一个学生类
      function Stu(name, age){
        this.name = name;
        this.age = age;
        this.show = function(){
          window.alert(this.name + " " + this.age);
        }
      }

      //中学生
      function MidStu(name, age) {
        this.stu = Stu;
        // 通过对象冒充来实现继承的
        // 对象冒充的意思就是获取那个类的所有成员,因为js是谁调用那个成员就是谁的,这样MidStu就有了Stu的成员了
        this.stu(name, age);
        //判断结论
        this.show_mid = function(){
          window.alert("我的名字是" + this.name);
        }

        //收费方式
        this.payFee = function(){
          window.alert("缴费" + money * 0.8);
        }
      }

      //小学生
      function Pupil(name, age) {
        this.stu = Stu;
        // 通过对象冒充来实现继承的
        this.stu(name, age);

        //收费方式
        this.payFee = function(){
          window.alert("缴费" + money * 0.5);
        }
      }

      //实例一个中学生
      var midStu = new MidStu("zs", 13);
      midStu.show(); //zs  13
      midStu.show_mid(); //我的名字是zs
      var pupil = new Pupil("ls", 10); //ls 10
      pupil.show();
    script>
  head>
  <body>
  body>
html>

二、通过call或者apply实现
第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:

function Animal(){
    this.species = "动物";

  }

function Cat(name,color){
      Animal.apply(this, arguments);
    this.name = name;
    this.color = color;

  }

三、 prototype模式

如果”猫”的prototype对象,指向一个Animal的实例,那么所有”猫”的实例,就能继承Animal了。

  Cat.prototype = new Animal();  // 代码的第一行,我们将Cat的prototype对象指向一个Animal的实例。

  Cat.prototype.constructor = Cat;
  // 原来,任何一个prototype对象都有一个constructor属性,指向它的构造函数。如果没有"Cat.prototype = new Animal();"这一行,Cat.prototype.constructor是指向Cat的;加了这一行以后,Cat.prototype.constructor指向Animal。
  var cat1 = new Cat("大毛","黄色");

  alert(cat1.species); // 动物

由于Animal对象中,不变的属性都可以直接写入Animal.prototype。所以,我们也可以让Cat()跳过 Animal(),直接继承Animal.prototype。
现在,我们先将Animal对象改写:
 

 function Animal(){ }
  Animal.prototype.species = "动物";
然后,将Cat的prototype对象,然后指向Animal的prototype对象,这样就完成了继承。
  Cat.prototype = Animal.prototype;
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。

四、利用空对象作为中介
由于”直接继承prototype”存在上述的缺点,所以就有第四种方法,利用一个空对象作为中介。

var F = function(){};
  F.prototype = Animal.prototype;
  Cat.prototype = new F();
  Cat.prototype.constructor = Cat;

面是采用prototype对象,实现继承。我们也可以换一种思路,纯粹采用”拷贝”方法实现继承。简单说,如果把父对象的所有属性和方法,拷贝进子对象,不也能够实现继承吗?这样我们就有了第五种方法。
首先,还是把Animal的所有不变属性,都放到它的prototype对象上。
  

function Animal(){}
  Animal.prototype.species = "动物";
然后,再写一个函数,实现属性拷贝的目的。
  function extend2(Child, Parent) {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
      c[i] = p[i];
      }
    c.uber = p;
  }

这个函数的作用,就是将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象。
使用的时候,这样写:

  extend2(Cat, Animal);
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

借鉴之处

你可能感兴趣的:(JS)