原型继承与构造函数继承
原型链 Prototype Chaning
function Animal(){
this.names = ['animal', 'zoom', 'beast', 'creature']
this.say = function(index){
console.log(`I am ${this.names[index]}`)
}
}
var oneAnimal = new Animal()
oneAnimal.say(1) // I am zoom
每一个方法都有原型,我们可以在原型链挂载属性或者方法,原型在方法和通过new方法产生的实例之间分享:
function Animal(){
}
Animal.prototype.names = ['animal', 'zoom', 'beast', 'creature']
Animal.prototype.say = function(index){
console.log(`I am ${this.names[index]}`)
}
var oneAnimal = new Animal()
oneAnimal.say(1)
//> I am zoom
原型链最大的好处是实例间可以复用:
var anotherAnimal = new Animal()
anotherAnimal.say(2)
//> I am beast
接着说一下原型链是怎么继承的:
function Animal(){
}
Animal.prototype.names = ['animal', 'zoom', 'beast', 'creature']
Animal.prototype.say = function(index){
console.log(`I am ${this.names[index]}`)
}
function Cat(){
this.whiskers = 8
}
// 从Animal中继承
Cat.prototype = new Animal()
var kitten = new Cat()
kitten.say(2) //> I am beast
4
原型链有两个大问题,一个是引用值在实例之间互用:
var kitten = new Cat()
var oldCat = new Cat()
kitten.names.push('kitten')
oldCat.say(4) //> I am kitten
第二个问题是,在创建实例的时候,不能传参给父类构造器。
原型式继承 Prototypal Inheritance
在之前的例子中,我们需要先自定义一个Animal父类,然后再定义Cat子类去继承它,原型式继承的作用是跳过第一步,使用一个现成的类直接继承。
function create(fatherInstance){
function Son(){}
Son.prototype = fatherInstance
return new Son()
}
这个就是原型式继承,Object.create()就是使用这种方式:
借用构造函数继承
这种技术的基本思想很简单,就是在子类型的构造函数中调用超类型构造函数。其代码演示如下:
function SuperType() {
this.colors = ['red', 'blue', 'green']
}
function SubType() {
//继承SuperType
SuperType.call(this)
}
var instance1 = new SubType()
instance1.colors.push('black')
alert(instance1.colors) //red,blue,green,black
var instance2 = new SubType()
alert(instance2.colors) //red,blue,green
相对于原型链而言,借用构造函数有一个很大的优势,就是在子类型构造函数中向超类型构造函数传递参数。但该方法也存在一个问题,函数服用无从谈起。