构造函数的继承

继承的方法有很多,有的存在明显缺点,我选择了以下三种方法来记忆并使用。

1.使用prototype,并利用空对象作为中介

(摘自avascript面向对象编程(二):构造函数的继承)

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

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

F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
alert(Animal.prototype.constructor); // Animal
我们将上面的方法,封装成一个函数,便于使用。

  function extend(Child, Parent) {

    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.uber = Parent.prototype;
  }

使用的时候,方法如下

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

这个extend函数,就是YUI库如何实现继承的方法。
另外,说明一点,函数体最后一行
Child.uber = Parent.prototype;
意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。(uber是一个德语词,意思是"向上"、"上一层"。)这等于在子对象上打开一条通道,可以直接调用父对象的方法。这一行放在这里,只是为了实现继承的完备性,纯属备用性质。

2.拷贝继承

(摘自avascript面向对象编程(二):构造函数的继承)
上面是采用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); // 动物

3.Object.create

ES5中定义了该方法。使用它,可以很简单地完成继承。

实例1

var Parent = {
    getName: function() {
        return this.name;
    }
}
 
var child = Object.create(Parent, {
    name: { value: "Benjamin"},
    url : { value: "http://www.zuojj.com"}
});
 
//Outputs: Object {name: "Benjamin", url: "http://www.zuojj.com", getName: function}
console.log(child);
 
//Outputs: Benjamin
console.log(child.getName());

实例2

var Parent = {
    getName: function() {
        return this.name;
    },
    getSex: function() {
        return this.sex;
    }
}
 
var Child = Object.create(Parent, {
    name: { value: "Benjamin"},
    url : { value: "http://www.zuojj.com"}
});
 
var SubChild = Object.create(Child, {
    name: {value: "zuojj"},
    sex : {value: "male"}
})
 
//Outputs: http://wwww.zuojj.com
console.log(SubChild.url);
 
//Outputs: zuojj
console.log(SubChild.getName());
 
//Outputs: undefined
console.log(Child.sex);
 
//Outputs: Benjamin
console.log(Child.getName());

你可能感兴趣的:(构造函数的继承)