1.什么繼承求晶?
繼承就是某個(gè)對象可以訪問另一個(gè)對象的屬性和方法章姓,我們認(rèn)為他們之間存在繼承關(guān)系席楚。
舉例:
function Chinese(){}
var jack=new Chinese();
//jack可以訪問到自身的屬性讶凉,還可以訪問到Chinese.prototype對象中的屬性和方法问欠,
//--->我們說jack繼承自Chinese.prototype
//--->jack.__proto__===Chinese.prototype
2.繼承主流的實(shí)現(xiàn)方式:
1.原型式繼承
a.擴(kuò)展原型對象
function Person(){}
//一個(gè)函數(shù)創(chuàng)建好之后,就會又一個(gè)默認(rèn)的原型對象感昼,需要給這個(gè)對象添加屬性装哆、方法,我們把這樣的方式稱之為擴(kuò)展原型對象實(shí)現(xiàn)繼承
Person.prototype.run=function(){
console.log("run");
};
var p1=new Person();
console.log(p1.constructor);//Person
//p1
//p1.__proto__--->Person.prototype
console.log(p1.run);
//有時(shí)候我們需要給原型對象中擴(kuò)展多個(gè)屬性和方法定嗓,如果使用擴(kuò)展原型對象來實(shí)現(xiàn)蜕琴,出現(xiàn)一些重復(fù)的代碼,我們思考能不能把這些重復(fù)封裝起來宵溅,解決方案:替換原型對象實(shí)現(xiàn)繼承
Person.prototype.run1=function(){
console.log("run");
};
Person.prototype.run2=function(){
console.log("run");
};
Person.prototype.run3=function(){
console.log("run");
};
Person.prototype.run4=function(){
console.log("run");
};
Person.prototype.run5=function(){
console.log("run");
};
b.替換原型對象
function Person(){}
//一個(gè)函數(shù)創(chuàng)建好之后凌简,就會又一個(gè)默認(rèn)的原型對象,需要給這個(gè)對象添加屬性恃逻、方法雏搂,我們把這樣的方式稱之為擴(kuò)展原型對象實(shí)現(xiàn)繼承
//替換原型對象
Person.prototype={
constructor:Person,
r1:function(){},
r2:function(){},
r3:function(){}
};
var p1=new Person();
console.log(p1.r1);//p1.__prpto__:Person.prototype
2.混入繼承(拷貝繼承)
function foo(name,age,gender,height,width,language,color){}
foo("zhangsan",20,"男",180,180,"中文","黃色");
function foo2(obj){
this.name=obj.name;
this.age=obj.age;
this.gender=obj.gender;
this.height=obj.height;
this.language=obj.language;
this.width=obj.width;
this.color=obj.color;
//上面的代碼又產(chǎn)生了很多的重復(fù)的字符,就希望有某種方式可以減少重復(fù)
//解決方案:混入繼承:for...in循環(huán)
for (var key in obj) {//key保存了obj中每一個(gè)屬性的名稱:字符串的值
//獲取指定屬性的值:
this[key]=obj[key];//舉例:this["name"]=obj["name"]
}
}
foo2({
name:"zhagnsan",age:18,
gender:"男",height:180,width:200,language:"英語",
color:"白色"
});
/**
* 將某個(gè)對象中的屬性分別拷貝到另一個(gè)對象中
* 把提供數(shù)據(jù)的對象稱之為數(shù)據(jù)源對象(source object)
* 把接收數(shù)據(jù)的對象稱之為目標(biāo)對象(target object)
*/
function mixin(target,source){
for (var key in source) {
//將source中的指定的屬性拷貝到target中-->給target添加同名屬性
target[key]=source[key];
}
//告訴用戶拷貝的結(jié)果:
return target;
}
var o1={name:"zhagnsan",age:25,gender:"男"};
var o2={};
console.log(mixin(o2,o1));
var o3={name:"zhagnsan",age:25,gender:"男"};
var o4={length:10,gender:"女"};
console.log(mixin(o4,o3));//o4-->{name:"zhangsan",age:25,gender:"男",length:10}
3.原型式繼承(經(jīng)典繼承)
//原型式繼承:經(jīng)典繼承-->由道格拉斯在蝴蝶書(javascript語言精粹)中提出
function mixin(target,source){
for (var key in source) {
//將source中的指定的屬性拷貝到target中-->給target添加同名屬性
target[key]=source[key];
}
//告訴用戶拷貝的結(jié)果:
return target;
}
var o3={name:"zhagnsan",age:25,gender:"男"};
var o4={length:10,gender:"女"};
//希望o4中可以訪問到length/gender:"女"/-->name/age
//實(shí)現(xiàn)思路:讓o3和o4之間產(chǎn)生某個(gè)聯(lián)系(繼承關(guān)系)
// -->o4繼承自o3
// -->o4.__proto__==o3 -->o4就不僅可以訪問到自己的屬性寇损,也可以正常訪問到o3的一些屬性
//不能直接使用:o4.__proto__==o3凸郑,因?yàn)開_proto__屬性是非標(biāo)準(zhǔn)屬性,具有瀏覽器兼容性問題
//曲線救國的方式:
//想到之前:function Person(){} var p1=new Person(); p1.__proto__===Person.prototype
//為了實(shí)現(xiàn)上面的關(guān)系矛市,需要進(jìn)行相關(guān)的轉(zhuǎn)換芙沥,也就是通過某個(gè)構(gòu)造函數(shù)創(chuàng)建一個(gè)實(shí)例o4,執(zhí)行構(gòu)造函數(shù)的原型指向o3
function F(){}
F.prototype=o3;//讓F的實(shí)例都可以訪問到o3中的屬性
var o5=new F();//o5.__proto__===o3
o5.length=10;
o5.gender="女";
console.log(o5.length);//自己的length
console.log(o5.gender);//自己的gender
console.log(o5.name);//自己沒有,訪問o3的name屬性
//總結(jié):
//原型式繼承的功能:創(chuàng)建一個(gè)新的對象而昨,讓新的對象可以繼承自指定的對象救氯,從而這個(gè)新的對象既可以訪問到自己的屬性,也可以訪問到指定的對象的屬性
//現(xiàn)代瀏覽器中:Object.create()實(shí)現(xiàn)了原型式繼承(經(jīng)典繼承)
//ES5(js語言規(guī)范的第五個(gè)版本)——Object.create()--->IE9以下不支持
//var o6=Object.create(o3);//o6繼承自o3
//如果希望寫出一段代碼配紫,實(shí)現(xiàn)原型式繼承径密,讓它可以兼容所有的瀏覽器
//執(zhí)行過程:首先判斷瀏覽器是否存在這個(gè)方法,如果不存在躺孝,這個(gè)瀏覽器自己沒有實(shí)現(xiàn)經(jīng)典繼承享扔,就幫他實(shí)現(xiàn)
// 如果已經(jīng)存在,就不需要進(jìn)行任何操作
//經(jīng)過上面的處理之后植袍,就實(shí)現(xiàn)了可以在任意瀏覽器版本中惧眠,可以調(diào)用Object.create()
if(!Object.create){
Object.create=function(parent){
function F(){}
F.prototype=parent;
return new F();
};
}
alert(Object.create.toString());
var o7=Object.create(o3);//o6繼承自o3
alert(o7.name);
4.借用構(gòu)造函數(shù)繼承
5.寄生繼承、寄生組合于个、組合繼承