1.原型链继承
不考虑函数参数的情况下,我这样写
function Animal(){
this.family=['father','mother'];
this.age=12;
}
function Cat(){}
Cat.prototype=new Animal();
var cat=new Cat();
// console.log(cat.family); //可以正常输出
// console.log(cat.age);
cat.family.push('sister'); //cat改变family属性
console.log(cat.family);//改变已经体现
var cat1=new Cat(); //创建第二个实例
console.log(cat1.family);//也出现了“sister”,所有的实例都被改变,这显然不是我们想要的结果
var animal=new Animal();
console.log(animal.family);//父类Animal没有改变,由此说明只是Cat发生了永久改变,所有的new Cat()实例都将体现该变化
考虑接受参数的情况
function Animal(age){
this.family=['father','mother'];
this.age=age;
}
function Cat(age){
}
Cat.prototype=new Animal();
var cat=new Cat(12);
console.log(cat.age);//undefined,参数传递失败,显然我们不能为每个实例单独传递参数
2.对象冒充
参数传递的问题,我们使用call(或者apply)解决
function Animal(age){
this.family=['father','mother'];
this.age=age;
}
function Cat(cat_age){
Animal.call(this,cat_age)//Cat的this指向Animal对象,并且将参数cat_age传递到Animal
}
var cat=new Cat(12);
console.log(cat.age);//12,在使用call的情况下参数传递问题已经解决
再来看看这种方式有没有解决原型链继承中一个实例属性改变导致所有实例属性改变的问题
function Animal(age){
this.family=['father','mother'];
this.age=age;
}
function Cat(cat_age){
Animal.call(this,cat_age)//Cat的this指向Animal对象,并且将参数age传递到Animal
}
var cat=new Cat(12);
cat.family.push('sister');
console.log(cat.family);//father,mother,sister
var cat1=new Cat(12);
console.log(cat1.family);//father,mother问题已经解决
这种方式实现的继承是不是完美无缺呢??看下面代码
function Animal(age){
this.family=['father','mother'];
this.age=age;
this.getInfo=function(){
return this.age+' '+this.family;
}
}
function Cat(cat_age){
Animal.call(this,cat_age)//Cat的this指向Animal对象,并且将参数age传递到Animal
}
var cat=new Cat(12);
var cat1=new Cat(13);
console.log(cat.getInfo());//12 father,mother
console.log(cat1.getInfo());//13 father,mother
console.log(cat.getInfo==cat1.getInfo);//false
说明两个实例调用的是不同的getInfo()函数,我们希望getInfo()函数是可以复用的,不需要创建多个,我们考虑用继承来解决这个问题
function Animal(age){
this.family=['father','mother'];
this.age=age;
}
Animal.prototype.getInfo=function(){
return this.age+' '+this.family;
}
function Cat(cat_age){
Animal.call(this,cat_age)//Cat的this指向Animal对象,并且将参数age传递到Animal
}
var cat=new Cat(12);
var cat1=new Cat(13);
console.log(cat.getInfo==cat1.getInfo);//true
console.log(cat.getInfo());//报错
console.log(cat1.getInfo());//报错
说明cat和cat1访问不到Animal原型上的东西
那怎么解决呢??接下来学习没毛病的组合继承,这也是最常用的一种继承方式
3.组合继承
function Animal(age){
this.family=['father','mother'];
this.age=age;
}
Animal.prototype.getInfo=function(){
return this.age+' '+this.family;
}
function Cat(cat_age){
Animal.call(this,cat_age)//Cat的this指向Animal对象,并且将参数age传递到Animal
}
Cat.prototype=new Animal();
var cat=new Cat(12);
var cat1=new Cat(13);
console.log(cat.getInfo==cat1.getInfo);//true
console.log(cat.getInfo());//12 father,mother
console.log(cat1.getInfo());//13 father,mother
好了,组合继承成功将原型链继承和对象冒充的缺陷弥补,并继承了他们所有优点,没毛病