面向对象的四种继承方式
第一种继承:使用call,apply方法,将父对象的构造函数绑定在子对象上
function Xs(){
this.type = "学生";
}
function Dxs(name,age,sex){
Xs.call(this,arguments); //最简单的办法:构造函数的绑定
//使用call或者apply方法,将父对象的构造函数绑定在子对象
this.name = name;
this.age = age;
this.sex = sex;
}
function Xxs(name,age,sex){
Xs.apply(this,arguments);
this.name = name;
this.age = age;
this.sex = sex;
}
var xm = new Dxs("小明",18,"男");
var xh = new Xxs("小花",8,"女");
console.log(xm); //Dxs{"小明",18,"男","学生"}
console.log(xh);//Xxs{"小花",8,"女","学生"}
第二种继承:通过原型对象(ptototype),可以把属性和方法绑定到我们的对象上
function Xs(){
this.type = "学生";
}
function Dxs(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Dxs.prototype = new Xs(); //把Xs的type属性给了Dxs的原型对象上面
//这句话是将Dxs的prototype指向Xs,他会删除Dxs.prototype原本的值,并赋予一个新的值(Xs的值)
Dxs.prototype.constructor = Dxs; //将Dxs的原型对象继承Xs的实例后重新指向Dxs
var xm = new Dxs("小明",18,"男");
console.log(xm);
console.log(Dxs.prototype.constructor == Dxs)//Dxs.prototype = new Xs();存在时输出false,不存在时 是true
console.log(Dxs.prototype.constructor == Xs) //true
第三种继承:直接继承(protorype写在函数外面)
function Xs(){}//空函数
Xs.prototype.type = "学生";
function Dxs(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Dxs.prototype = Xs.prototype; //赋值,把Xs的原型对象赋值给了Dxs的原型对象;
//通过这句话,Dxs的原型对象继承自了学生,绑定了Xs的本体,那么,他们两个就绑定在了一起
Dxs.prototype.constructor = Dxs; //这句话,相当于同时把Dxs的原型对象和Xs的原型对象都指向Dxs
var xm = new Dxs("小明",18,"男");
console.log(xm);
console.log(Dxs.prototype.constructor == Xs.prototype.constructor) //true
//优点:效率比较高,不占用内存,第二个继承,实例化了Xs,那么就要占用一个空间,这个方法没有实例化Xs,就不用占用一个多余的空间
//缺点:Dxs.prototype和Xs的原型对象指向同一个对象了
第四种继承:利用空对象作为中介
var F = function(){}; //创建空对象
function Xs(){}; //创建父对象
Xs.prototype.type = "学生";
F.prototype = Xs.prototype;//空对象的原型对象继承父对象
function Dxs(name,age){ //子对象
this.name = name;
this.age = age;
}
Dxs.prototype = new F();//子对象继承空对象
Dxs.prototype.constructor = Dxs;//指针重新指回自己
var xm = new Dxs("小明",18);
console.log(xm.type);
console.log(Xs.prototype.constructor == Dxs);
//第一步,创建一个空函数
//第二步,创建父对象
//第三步,空对象的原型对象继承父对象
//第四,创建子对象
//第五步:子对象继承空对象
//那么Dxs.prototype.constructor = Dxs就不会改变父对象的prototype
//空对象不占用内存,Dxs继承的是空对象,所以不会改变父对象Xs的指向,至于空对象影不影响无所谓
继承封装
function extend(child,parent){
var c = child.prototype;
var p = parent.prototype;
for(var i in p){
c[i] = p[i];
}
}
function Xs(){};
Xs.prototype.type = "学生";
function Dxs(name,age){
this.name = name;
this.age = age;
}
extend(Dxs,Xs)
var xm = new Dxs("小明",18);
console.log(xm.type);
console.log(Xs.prototype.constructor == Xs);