<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>构造函数的继承</title>
<script>
function Animal(){
this.species="动物";
this.aread="中国";
}
function Cat(name,color){
this.name=name;
this.color=color;
}
//如何让猫继承动物呢?
//第一种方法:构造函数绑定
/*function Animal(){
this.species="动物";
}
function Cat(name,color){
Animal.call(this,arguments);//将父对象的构造函数绑定在子对象上实现继承
this.name=name;
this.color=color;
}
var cat=new Cat("小花","red");
alert(cat.species);*/
//缺点:不能继承原型上的属性和方法;
//第二种方法使用Prototype方法
/*function Animal(){
this.species="动物";
}
function Cat(name,color){
this.name=name;
this.color=color;
}
Cat.prototype=new Animal();
Cat.prototype.constructor=Cat;
var cat=new Cat("小花","red");
alert(cat.constructor==Cat);*/
//缺点:假如子类的prototype属性有值将会背覆盖
//注意:当改了prototype对象的constructor时,记得改回来,否则将造成继承链紊乱;
//第三种方法:实际上是对第二种方法的,由于Animal.prototype定义的属性是不变的,所以可以让Cat跳过Animal()直接继承Animal.prototype,可节省内存
/*function Animal(){
}
Animal.prototype.spcies="动物";
function Cat(name,color){
this.name=name;
this.color=color;
}
Cat.prototype.family="天河公园";
Cat.prototype=Animal.prototype;
//由于Prototype是和构造函数连起来的,只有有函数函数才能用prototype,这说明了当Cat的prototype对象发生改变时候,他的构造函数也会发生改变
alert(Cat.prototype.constructor==Animal)//true
//所以必须改变Cat的构造函数,以免发生继承紊乱
Cat.prototype.constructor=Cat;
var cat=new Cat();
cat.constructor("小花","red"); //两种写法哦
alert(cat.color);
alert(cat.family);//undefined
//缺点:如果子对象的prototype对象上有属性或方法时,将被清除;且子对象的prototype对象修改后父对象的prototype也会被修改;
*/
//第四种方法,是对第三种方法做的改进,利用空对象作为中介,使Cat.prototype对象的更改不会影响到Animal的Prototype对象
//var F=function(){}//空对象不占内存
/*function Animal(){
this.species="动物";
}*/
//F.prototype=Animal.prototype;
/*function Cat(name,color){
this.name=name;
this.color=color;
}*/
//Animal.prototype.species="动物";
/*function extend(Child,Parent){
try{
var F=function(){}
F.prototype=Parent.prototype;
Child.prototype=new F();
Child.prototype.constructor=Child;
//意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。(uber是一个德语词,意思是"向上"
//、"上一层"。)这等于在子对象上打开一条通道,可以直接调用父对象的方法。这一行放在这里,只是为了实现继承的完备性,纯属备用性质
Child.uder=Parent.prototype;
alert(Child.uder)
}catch(e){alert(e)}
}
extend(Cat,Animal);
var cat=new Cat("小黄","yellow");*/
//alert(cat.uder);
//第五中方法是拷贝继承,把父对象中不变的是属性写到prototype属性中
Animal.prototype.species="动物";
function extend(Child,Parent){
var p=Parent.prototype;
var c=Child.prototype;
for(var i in p){
c[i]=p[i];
}
c.uder=p;
}
extend(Cat,Animal);
var cat=new Cat();
alert(cat.species);
//缺点:只能继承原型上的属性和方法
//优点:如果子对象的prototype对象上有属性或方法时,不会被清除,且子对象的prototype对象修改后父对象的prototype不会被修改;
//第四种方法子对象的prototype修改后,中介F的prototype会修改,父对象不会。
</script>
</head>