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來循環(huán)遍歷原型對(duì)象的屬性,然后一一賦值給我們的空對(duì)象,從而實(shí)現(xiàn)了“繼承”。這個(gè)思路很正確,下面我們來對(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è)置無效,因?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改變,說明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ì)象來表示) 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了?!?/p>
總結(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-11JavaScript基礎(chǔ)進(jìn)階之?dāng)?shù)組方法總結(jié)(推薦)
下面小編就為大家?guī)硪黄狫avaScript基礎(chǔ)進(jìn)階之?dāng)?shù)組方法總結(jié)(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09js實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)重定向的幾種方式
這篇文章主要介紹js實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)重定向的幾種方式,需要的朋友可以參考下2014-05-05js實(shí)現(xiàn)鼠標(biāo)劃過給div加透明度的方法
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)劃過給div加透明度的方法,涉及javascript動(dòng)態(tài)操作頁(yè)面元素屬性的相關(guān)技巧,該方法可兼容火狐與IE瀏覽器,需要的朋友可以參考下2015-05-05js實(shí)現(xiàn)String.Fomat的實(shí)例代碼
下面小編就為大家?guī)硪黄猨s實(shí)現(xiàn)String.Fomat的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧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-10JS動(dòng)態(tài)添加與刪除select中的Option對(duì)象(示例代碼)
本篇文章主要介紹了JS動(dòng)態(tài)添加與刪除select中的Option對(duì)象示例代碼。需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-12-12