JavaScript繼承 其原理就是子類能調(diào)用父類的所有方法,父類的所有方法包括,父類自己 所有和 父類的原型所有,所以子類要實(shí)現(xiàn)繼承父類,可以有兩種思路
第一種 是子類復(fù)制父類原型的所有方法,然后通過call,或者是apply方法來獲得父類自己方法的調(diào)用權(quán).
第二種是子類通過原型鏈來獲得父類原型內(nèi)方法的調(diào)用權(quán),然后通過call,或者是apply方法來獲得父類自己方法的調(diào)用權(quán).
第一種,基于復(fù)制的實(shí)現(xiàn)
function Persion(){
this.name = "dasd";
this.getName = function(){
return this.name;
}
}
Persion.prototype.getAge = function(){
return "dun";
}
function base1(cl,sup,args){
var o = {};
var clp = cl.constructor.prototype;
var spp = sup.prototype;
for(var l in clp){ //標(biāo)記子類中已存在的方法
if(clp[l]){
o[l] = 1;
}
}
for(var k in spp){
if(!o[k]){ //如果方法在子類中不存在
clp[k] = spp[k]; //復(fù)制
}
}
sup.apply(cl,args); //改變父類this的指向子類,即子類獲取了父類方法的代用權(quán)
}
function ManPersion(){
base(this,Persion,[]);
}
var man = new ManPersion();
console.log(man.getName());//dasd
console.log(man.getAge());//dun
第二種,基于原型鏈的實(shí)現(xiàn)
function Persion(){
this.name = "dasd";
this.getName = function(){
return this.name;
}
}
Persion.prototype.getAge = function(){
return "dun";
}
var persion = new Persion();
console.log(Persion.prototype.__proto__ === Object.prototype);//true
console.log(Persion.__proto__ === Function.prototype);//true
console.log(Function.prototype.__proto__ === Object.prototype);//true
//基于以上推測實(shí)現(xiàn)繼承
function base(cl,sup,args){
//原型鏈綁定
cl.constructor.prototype.__proto__ = sup.prototype;
sup.apply(cl,args);//改變父類this的指向子類,即子類獲取了父類方法的代用權(quán)
}
function ManPersion(){
base(this,Persion,[]);
}
var man = new ManPersion();
console.log(man.getName());//dasd
console.log(man.getAge());//dun
完美實(shí)現(xiàn)繼承,不過估計(jì)在那些不支持__proto__屬性的瀏覽器上不能用,不過在所有的現(xiàn)代瀏覽器上比如chrome或者firefox上應(yīng)該都能用