《JavaScript高级程序设计》中涉及到的继承方式:原型链,借用构造函数,组合继承,原型式继承,寄生式继承,寄生组合式继承。函数
不要紧,我当时看完第一遍也是实力懵逼。后来反反复复学了好多遍,总算搞清楚了(特别是寄生组合式继成。)接下来就尽可能用浅显易懂的方式总结一遍。测试
一.原型链:this
原型我就不过多介绍了,有时间会写博客总结。prototype
先说说重写原型对象。什么是重写原型对象?就是以对象字面量的形式来从新定义原型对象的属性和方法。设计
好比:指针
function Person{ } Person.prototype = { name : "Nico", age : 20, job : "FE", sayName : function(){ alert(this.name); } }
以上以对象字面量重写原型对象以后,原型对象的constructor再也不指向Person了。由于每建立一个函数,就会同时建立它的prototype对象,这个对象也自动得到constructor属性,所以,新的原型对象的constructor如今指向Object构造函数,能够经过constructor:Person这么一句加强对象。不过这样会将它的[[Enumerable]]特性设置为true,能够经过Object.defineProperty()来设置。具体就不作扩展了。code
这里特意提到是由于要告诉米娜桑,若是建立实例以后从新了原型对象,实例仍指向最初的原型对象。因此实例使没法调用新添加的方法和属性的。因此,在经过原型链实现继承时,不能使用对象字面量建立原型方法。对象
好了继续说原型链继承。实现方式是让原型对象等于另外一个类型的实例。结果会怎样?此时的原型对象包含指向另外一个原型的指针[[prototype]],相应地,另外一个原型中也包含着一个指向另外一个构造函数的指针constructor。如此以来层层递进,构成了实例与原型的链条。继承
先看一个例子。ip
function superType(){ this.property = true; } superType.prototype.getSuperValue = function(){ return this.property; } function subType(){ this.subproperty = false; } //继承了superType subType.prototype = new superType(); subType.prototype.getSubValue = function(){ return this.subProperty; } var instance = new subValue(); alert(instance.getSuperValue);
以上的代码没有使用subType默认提供的原型,而是给它换了一个新原型,即superType的实例。如此一来,superType的全部的实例属性和实例方法被添加到subType的原型对象之中,由于此时subType的原型是superType的实例,因此实例属性和方法天然而然会被添加到实例之中。subType的原型对象也会多出一个[[prototype]]属性指向superType,这样造成一个原型链,实例instance访问getSuperType()方法时,会通过三个步骤:(1)搜索实例,(2)搜索subType.prototype,(3)搜索superType.prototype。搜索过程是一环一环前行到原型链末端才会停下来。(注意,instance.constructor如今指向的是superType,由于subType的原型指向了另外一个对象——superType的原型,而superType的原型的constructor指向的是superType。)
二.别忘记默认的原型:
全部函数的默认原型都是Object的实例,所以默认原型都会包含一个内部指针,指向Object.prototype。
三.肯定原型和实例的关系:
1>使用instanceof()操做符。只要用这个操做符来测试实例与原型链中出现过的构造函数,结果就会返回true。
alert(instance instanceof Object) //true alert(instance instanceof superType) //true alert(instance insatanceof subType) //true
2>使用isPrototypeOf()方法。只要是原型链中出现过的原型,均可以说是该原型链所派生的实例的原型。
alert(Object.prototype.isPrototypeOf(instance)) //true alert(superType.prototype.isPrototypeOf(instance)) //true alert(subType.prototype.isPrototypeOf(instance)) //true
四.原型链的问题
1>包含引用类型值的原型属性会被全部实例共享。
2>在建立子类型的实例时,不能向超类型的构造函数中传递参数。