原型继承
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.say=function(){
alert(this.name+" is garbage!");
};
function Man(){
}
Man.prototype=new Person('霍顿',22);//这句是重点,敲黑板
var man1=new Man();
man1.say();
var man2=new Man();
alert(man2.name);
alert(man2.age);
//这种继承方式很直接,为了获取person的所有属性方法直接将父类的实例赋给了子类
//的原型,其实子类的实例本身是一个完全空的对象,所有的属性和方法都得去原型链上去找
//因而找到的属性方法都是同一个,所以直接利用原型链继承是不现实的。
构造继承
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.say=function(){
alert(this.name+" is garbage!");
}
function Man(name,age){
Person.apply(this,arguments);//这句是重点,敲黑板
}
var man1=new Man('霍顿');
alert(man1.name);
man1.say();//没有输出,无法调用
//利用构造函数继承,在子类的构造函数里利用了apply去调用父类的构造函数,从而达到继承父类属性的效果
//比直接利用原型链要好,但这种方法只能继承父类的实例属性因而找不到say方法,为了继承父类的属性和方法引入了组合继承方式
组合继承
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.say=function(){
alert(this.name+" is garbage!");
};
function Man(name,age){
Person.apply(this,arguments);//这句是重点,敲黑板
}
Man.prototype=new Person();//这句是重点,敲黑板
var man1=new Man("霍顿");
var man2=new Man("霍顿他爹");
alert(man1.name);
alert(man1.say());
//需要注意的是man1的实例属性其实是覆盖了原型属性但是并没有要覆盖掉原型上的say方法
//所以man1.say==man2.say依然返回true,因而需要十分小心没有覆盖掉的原型属性,
//因为它是所有实例共有的。
寄生继承
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.say=function(){
alert(this.name+" is garbage!")
};
function Man(name,age){
Person.apply(this,arguments);//这句是重点,敲黑板
}
Man.prototype=Object.create(Person.prototype);//这句是重点,敲黑板
Man.prototype.constructor=Man;//这句是重点,敲黑板
var man1=new Man("霍顿");
var man2=new Man("霍顿他爹");
alert(man1.say==man2.say);
alert(man1.say());
alert(man2.say());
//寄生组合继承和上面的组合继承区别仅在于构造子类原型对象的方式上
//这里用到了Object.create(obj)方式,该方法其实是对传入的obj对象进行浅拷贝