面向?qū)ο蟮乃姆N繼承方式
第一種繼承:使用call饺谬,apply方法临燃,將父對象的構(gòu)造函數(shù)綁定在子對象上
function Xs(){
this.type = "學(xué)生";
}
function Dxs(name,age,sex){
Xs.call(this,arguments); //最簡單的辦法:構(gòu)造函數(shù)的綁定
//使用call或者apply方法橱乱,將父對象的構(gòu)造函數(shù)綁定在子對象
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,"男","學(xué)生"}
console.log(xh);//Xxs{"小花",8,"女","學(xué)生"}
第二種繼承:通過原型對象(ptototype)办成,可以把屬性和方法綁定到我們的對象上
function Xs(){
this.type = "學(xué)生";
}
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的實(shí)例后重新指向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寫在函數(shù)外面)
function Xs(){}//空函數(shù)
Xs.prototype.type = "學(xué)生";
function Dxs(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Dxs.prototype = Xs.prototype; //賦值亮隙,把Xs的原型對象賦值給了Dxs的原型對象途凫;
//通過這句話,Dxs的原型對象繼承自了學(xué)生溢吻,綁定了Xs的本體维费,那么,他們兩個就綁定在了一起
Dxs.prototype.constructor = Dxs; //這句話促王,相當(dāng)于同時把Dxs的原型對象和Xs的原型對象都指向Dxs
var xm = new Dxs("小明",18,"男");
console.log(xm);
console.log(Dxs.prototype.constructor == Xs.prototype.constructor) //true
//優(yōu)點(diǎn):效率比較高犀盟,不占用內(nèi)存,第二個繼承蝇狼,實(shí)例化了Xs,那么就要占用一個空間阅畴,這個方法沒有實(shí)例化Xs,就不用占用一個多余的空間
//缺點(diǎn):Dxs.prototype和Xs的原型對象指向同一個對象了
第四種繼承:利用空對象作為中介
var F = function(){}; //創(chuàng)建空對象
function Xs(){}; //創(chuàng)建父對象
Xs.prototype.type = "學(xué)生";
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);
//第一步迅耘,創(chuàng)建一個空函數(shù)
//第二步贱枣,創(chuàng)建父對象
//第三步,空對象的原型對象繼承父對象
//第四豹障,創(chuàng)建子對象
//第五步:子對象繼承空對象
//那么Dxs.prototype.constructor = Dxs就不會改變父對象的prototype
//空對象不占用內(nèi)存冯事,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 = "學(xué)生";
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);