javascript 用函數(shù)實(shí)現(xiàn)繼承詳解
一、知識(shí)儲(chǔ)備:
1、枚舉屬性名稱的函數(shù):
(1)for...in:可以在循環(huán)體中遍歷對(duì)象中所有可枚舉的屬性(包括自有屬性和繼承屬性)
(2)Object.keys():返回?cái)?shù)組(可枚舉的自有屬性)
(3)Object.getOwnPropertyNames():所有的自有屬性
3、屬性的特性:數(shù)據(jù)屬性和存取器屬性
(1)數(shù)據(jù)屬性:可寫(writable) 可枚舉(enumerable) 可配置(configurable) 值(value)
數(shù)據(jù)屬性只有一個(gè)簡(jiǎn)單的值;
(2)存取器屬性: 寫入(set) 讀?。╣et) 可枚舉(enumerable) 可配置(configurable)
存取器屬性不可寫(即沒有writable特性)。
屬性有set方法,那這個(gè)屬性是可寫的,有g(shù)et方法,那這個(gè)屬性就是可讀的。
4、定義屬性特性的方法:Object.defineProperty(對(duì)象,屬性,描述符對(duì)象)
5、獲取屬性的描述符對(duì)象:Object.getOwnPropertyDescriptor(對(duì)象,屬性)
二、示例
1、根據(jù)for...in的用法,我們可以寫出模擬“繼承”的方法:
<script type="text/javascript">
var child={};
var mother={
name:"zhangzhiying",
lastAge:21,
sex:"女"
};
function extend(target,source){
for(var p in source){
target[p]=source[p];
}
return target;
}
extend(child,mother);
console.log(child); //<STRONG>Object {name: "zhangzhiying", lastAge: 21, sex: "女"}</STRONG>
</script>
2、使用for in來(lái)循環(huán)遍歷原型對(duì)象的屬性,然后一一賦值給我們的空對(duì)象,從而實(shí)現(xiàn)了“繼承”。這個(gè)思路很正確,下面我們來(lái)對(duì)以上示例進(jìn)行改造:
<script type="text/javascript">
var child={};
var mother={
name:"zhangzhiying",
lastAge:21,
<STRONG>set age(value){
this.lastAge=value;
},
get age(){
return this.lastAge+1;
},</STRONG>
sex:"女"
};<BR> <STRONG> mother.age=15;</STRONG> //有set方法,具有可寫性
function extend(target,source){
for(var p in source){
target[p]=source[p];
}
return target;
}
extend(child,mother);
console.log(child); //<STRONG>Object {name: "zhangzhiying", lastAge: 15, age: 16, sex: "女"}</STRONG>
</script>
可以看到代碼中使用了一對(duì)set,get;其中age是一個(gè)存取器屬性。
運(yùn)行的結(jié)果:一個(gè)不包含set,get的普通對(duì)象?!?/p>
結(jié)論:for in實(shí)現(xiàn)的“繼承”不處理set和get ,它把存取器屬性(age)轉(zhuǎn)換為一個(gè)靜態(tài)的數(shù)據(jù)屬性。
3、給mother對(duì)象設(shè)置數(shù)據(jù)屬性
<script type="text/javascript">
var child={};
var mother={
name:"zhangzhiying",
lastAge:21,
set age(value){
this.lastAge=value;
},
get age(){
return this.lastAge+1;
},
sex:"女"
};
Object.defineProperty(mother,"lastAge",{writable:false}); //把lastAge設(shè)置成了不可寫
mother.age=15; //設(shè)置無(wú)效,因?yàn)閘astAge的值不變,所以lastAge+1不變,即age不變
function extend(target,source){
for(var p in source){
target[p]=source[p];
}
return target;
}
extend(child,mother);
console.log(child); //Object {name: "zhangzhiying", lastAge: 21, age: 22, sex: "女"}
child.lastAge=12; //結(jié)果顯示lastAge改變,說(shuō)明child.lastAge沒有“繼承”到mother.lastAge的特性,我們?cè)儆胓etOwnPropertyDesriptor()方法確認(rèn)一下<BR> console.log(Object.getO
<EM id=__mceDel></script> </EM>
結(jié)論:要實(shí)現(xiàn)繼承,我們還需要解決的問題->“繼承”屬性特性。
4、完善版本
<script type="text/javascript">
var child={};
var mother={
name:"zhangzhiying",
lastAge:21,
set age(value){
this.lastAge=value;
},
get age(){
return this.lastAge+1;
},
sex:"女"
};
Object.defineProperty(mother,"lastAge",{writable:false});
mother.age=15;
<SPAN style="COLOR: #333399"><STRONG>function extend(target,source){
var names=Object.getOwnPropertyNames(source); //獲取所有的屬性名
for(var i=0;i<names.length;i++){
if(names[i] in target) continue; //如果這個(gè)屬性存在,就跳過(原型繼承中,如果自有屬性和原型對(duì)象的屬性重名,保留自有屬性)
var desc=Object.getOwnPropertyDescriptor(source,names[i]); //獲取mother屬性的描述符對(duì)象(即屬性特性的集合,es5中用描述符對(duì)象來(lái)表示)
Object.defineProperty(target,names[i],desc); //將mother的描述符對(duì)象給child的屬性定義
}
return target;
}</STRONG></SPAN>
extend(child,mother);
console.log(child);
child.lastAge=12;
console.log(Object.getOwnPropertyDescriptor(child,"lastAge"));
console.log(child);
</script>
最后的結(jié)果:

可以明顯看到三次的打印,child“繼承”到了set和get,lastAge數(shù)值沒發(fā)生變化,writable也是false了。
總結(jié):最近在看《javascript權(quán)威指南》,總結(jié)一點(diǎn)心得,有錯(cuò)誤歡迎指正,共同學(xué)習(xí)進(jìn)步~
以上這篇javascript 用函數(shù)實(shí)現(xiàn)繼承詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Canvas中繪制Geojson數(shù)據(jù)示例詳解
這篇文章主要為大家介紹了Canvas中繪制Geojson數(shù)據(jù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
JavaScript基礎(chǔ)進(jìn)階之?dāng)?shù)組方法總結(jié)(推薦)
下面小編就為大家?guī)?lái)一篇JavaScript基礎(chǔ)進(jìn)階之?dāng)?shù)組方法總結(jié)(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-09-09
js實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)重定向的幾種方式
這篇文章主要介紹js實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)重定向的幾種方式,需要的朋友可以參考下2014-05-05
js實(shí)現(xiàn)鼠標(biāo)劃過給div加透明度的方法
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)劃過給div加透明度的方法,涉及javascript動(dòng)態(tài)操作頁(yè)面元素屬性的相關(guān)技巧,該方法可兼容火狐與IE瀏覽器,需要的朋友可以參考下2015-05-05
js實(shí)現(xiàn)String.Fomat的實(shí)例代碼
下面小編就為大家?guī)?lái)一篇js實(shí)現(xiàn)String.Fomat的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2016-09-09
純Javascript實(shí)現(xiàn)Windows 8 Metro風(fēng)格實(shí)現(xiàn)
Windows 8 Metro風(fēng)格設(shè)計(jì),實(shí)現(xiàn)網(wǎng)站或系統(tǒng)功能的導(dǎo)航,在本文將為大家介紹下如何用純Javascript實(shí)現(xiàn)Windows 8 Metro風(fēng)格,感興趣的朋友可以參考下2013-10-10
JS動(dòng)態(tài)添加與刪除select中的Option對(duì)象(示例代碼)
本篇文章主要介紹了JS動(dòng)態(tài)添加與刪除select中的Option對(duì)象示例代碼。需要的朋友可以過來(lái)參考下,希望對(duì)大家有所幫助2013-12-12

