**这可是个重点 **

原型链继承

ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原 型让一个引用类型继承另一个引用类型的属性和方法

当然这就不得不谈,构造函数、原型、与实例的关系: 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念,实例如下:

  1. function SuperType(){
  2. this.property = true;
  3. }
  4. SuperType.prototype.getSuperValue = function(){
  5. return this.property;
  6. };
  7. function SubType(){
  8. this.subproperty = false;
  9. }
  10. //继承了 SuperType
  11. SubType.prototype = new SuperType();
  12. SubType.prototype.getSubValue = function (){
  13. return this.subproperty;
  14. };
  15. var instance = new SubType();
  16. alert(instance.getSuperValue()); //true

so,这一部分超出预期,多看看红宝书第六章第三小节“继承”吧!

借用构造函数

在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术(有时候也叫做伪造对象或经典继承)。即在子类型构造函数的内部调用超类型构造函数。别忘了,函数只不过是在特定环境中执行代码的对象,因此通过使用 apply()和 call()方法也可以在(将来)新创建的对象上执行构造函数:

  1. function SuperType(){
  2. this.colors = ["red", "blue", "green"];
  3. }
  4. function SubType(){
  5. //继承了 SuperType
  6. SuperType.call(this);
  7. }
  8. var instance1 = new SubType();
  9. instance1.colors.push("black");
  10. alert(instance1.colors); //"red,blue,green,black"
  11. var instance2 = new SubType();
  12. alert(instance2.colors); //"red,blue,green"

组合继承

也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性:

  1. function SuperType(name){
  2. this.name = name;
  3. this.colors = ["red", "blue", "green"];
  4. }
  5. SuperType.prototype.sayName = function(){
  6. alert(this.name);
  7. };
  8. function SubType(name, age){
  9. //继承属性
  10. SuperType.call(this, name);
  11. this.age = age;
  12. }
  13. //继承方法
  14. SubType.prototype = new SuperType();
  15. SubType.prototype.constructor = SubType;
  16. SubType.prototype.sayAge = function(){
  17. alert(this.age);
  18. };
  19. var instance1 = new SubType("Nicholas", 29);
  20. instance1.colors.push("black");
  21. alert(instance1.colors); //"red,blue,green,black"
  22. instance1.sayName(); //"Nicholas";
  23. instance1.sayAge(); //29
  24. var instance2 = new SubType("Greg", 27);
  25. alert(instance2.colors); //"red,blue,green"
  26. instance2.sayName(); //"Greg";
  27. instance2.sayAge(); //27

原型式继承

寄生式继承

寄生组合式继承

注:记住前三种