JavaScript 類的封裝操作示例詳解
本文實(shí)例講述了JavaScript 類的封裝操作。分享給大家供大家參考,具體如下:
一,首先,為什么要使用封裝?
這是從信息的角度出發(fā)的,信息的隱藏是最終的目的,而封裝只不過(guò)是實(shí)現(xiàn)隱藏的一種方法。
這里我們需要明白一點(diǎn)就是:類的定義有如下的三種方式:
(第一種)門(mén)戶大開(kāi)型方式 (第二種)用命令規(guī)范區(qū)別私有和公有的方式 (第三種)閉包
現(xiàn)在詳細(xì)描述一下每一種類的定義方式:
針對(duì)第一種,門(mén)戶大開(kāi)類型
首先,我們來(lái)看一種情況
(1)聲明一個(gè)簡(jiǎn)單的類,代碼如下
function Person(age,name) { this.name=name; this.age=age; }
?。?)實(shí)例化類+調(diào)用
var p=new Person(-10,"小明"); alert(p.age)//結(jié)果出現(xiàn)年齡出現(xiàn)負(fù)數(shù)
從上述的運(yùn)行結(jié)果中,我們可以看出程序可以正常執(zhí)行,但這并符合實(shí)際,因?yàn)槟挲g出現(xiàn) 了負(fù)數(shù),這不是我們想要的,我們需要一個(gè)能正確處理并產(chǎn)生與實(shí)際情況相符的解決方案。
為了能解決上述年齡出現(xiàn)的問(wèn)題,我們可以這樣做:擴(kuò)展類的原型鏈
Person.prototype={ checkAge:function (age) { if(0<age&&age<150){ return true; }else { return false; } } }
加上解決方案后,代碼如下
(1)基本類
function Person(age,name) { this.name=name; //調(diào)用方法判斷驗(yàn)證 if(!this.checkAge(age)){ throw new Error("年齡必須在0-150之間"); } this.age=age; }
(2)年齡判斷驗(yàn)證
Person.prototype={ checkAge:function (age) { if(0<age&&age<150){ return true; }else { return false; } } }
(3)調(diào)用
var p2=new Person(10,"小明"); alert(p2.age)
我們還可以給name添加一個(gè)讀取驗(yàn)證,name為空時(shí)使用默認(rèn)值 同樣是擴(kuò)展類的原型鏈
代碼如下,
Person.prototype["getName"]=function () { return this.name||"我是默認(rèn)的"; } //調(diào)用
var p3=new Person(10,""); alert(p3.getName())//結(jié)果為“我是默認(rèn)的”
總結(jié)一下:當(dāng)類被定義為門(mén)戶大開(kāi)類型時(shí)會(huì)出現(xiàn)與實(shí)際不符合的情況 ,雖然我們可以加在類上擴(kuò)展原型類加驗(yàn)證方法解決,但是這樣會(huì)使類變得臃腫。
針對(duì)第二種,用命名規(guī)范區(qū)別私有和公有
步驟如下,
(1)定義類 在類中定義變量(私有和公有變量)+驗(yàn)證方法的調(diào)用
//用命名規(guī)范來(lái)區(qū)別私有和公有 function Person(name,age,email) { //定義私有變量 this._name;//私有 this.setName(name);//只是方法的調(diào)用,方法中有驗(yàn)證,而不是在類中驗(yàn)證 this._age;//私有 this.setAge(age); this.email=email;//公有的 }
(2)在類的原型上面 擴(kuò)展賦值方法
Person.prototype={//直接擴(kuò)展至原型上,可以在本類的內(nèi)部使用this調(diào)用 setName:function (name) { this._name=name; }, setAge:function (age) { //需要做判斷符號(hào)實(shí)際情況 if(age>0&&age<150){//驗(yàn)證不在類中,類不會(huì)變的臃腫 this._age=age; }else { throw new Error("年齡必須是在0到150范圍內(nèi)") } } }
(3)應(yīng)用
var text1=new Person("測(cè)試",-10,"qq.com"); alert(text1._age)//-10 程序會(huì)報(bào)錯(cuò) 這是我們想要的(說(shuō)明驗(yàn)證是對(duì)的)
var p2=new Person("測(cè)試2",10,"qq.cpm"); alert(p2._age)//程序正常運(yùn)行 達(dá)到我們的目標(biāo)
總結(jié)一下:在類的定義是使用命名規(guī)范來(lái)定義私有變量和公有變量,并將驗(yàn)證方法和賦值方法擴(kuò)展到本類的原型鏈上,在類中調(diào)用方法即可(會(huì)有返回值),這樣不會(huì)導(dǎo)致類的臃腫。
針對(duì)第三種,閉包實(shí)現(xiàn)封裝
這種方式有點(diǎn)像高級(jí)語(yǔ)言,在定義類是使用get,set方法實(shí)現(xiàn)數(shù)據(jù)的操作
(1)定義一個(gè)基本類(變量+操作變量的方法)
function Person(name,age,email) { //(1)聲明變量和對(duì)變量進(jìn)行操作的get和set方法 this.email=email;//公有變量 //get方法 this.getName=function (name){ return this.name;//為什么是this調(diào)用呢?請(qǐng)看set方法 } this.getAge=function (age){ return this.age; } //set方法 這里相當(dāng)于在類上的擴(kuò)展 this.setName=function (name) { this.name=name;//Person.prototype.name 這里寫(xiě)明了get中this的寫(xiě)法的來(lái)源 } this.setAge=function (age) { if(age>0&&age<150){ this.age=age;//Person.prototype.name 這里寫(xiě)明了get中this的寫(xiě)法的來(lái)源 }else { throw new Error("年齡必須是在0到150范圍內(nèi)"); } } //(2)寫(xiě)一個(gè)構(gòu)造函數(shù) 做初始化 實(shí)現(xiàn)閉包 確保set是在get之前的,不然get時(shí)會(huì)出現(xiàn)錯(cuò)誤 this.init=function () { this.setName(name); this.setAge(age); } this.init();//顯示調(diào)用 }
(2)應(yīng)用
var p=new Person("text",-10,"qq.com"); alert(p.age)//程序由于不符合實(shí)際而被阻斷,符合要求
注:額外的閉包寫(xiě)法 var 方式
var _sex="M"; this.getSex=function () { return _sex; } this.setSex=function () { _sex=sex; }
總結(jié)一下:
(1)這里只是函數(shù)和屬性的簡(jiǎn)單封裝,還有更為復(fù)雜是業(yè)務(wù)需要封裝,使用get和set方法時(shí),需要一個(gè)構(gòu)造函數(shù)用于兩者先后順序的初始化實(shí)現(xiàn)閉包,之后顯示調(diào)用,確保set是在get之前的。
(2)閉包的實(shí)現(xiàn),是通過(guò)get和set實(shí)現(xiàn)的,this.方式賦值時(shí)沒(méi)有暴露在外面而是通過(guò)get,set方法實(shí)現(xiàn)閉包。
二,靜態(tài)化
普通屬性和函數(shù)是作用在對(duì)象上到,而靜態(tài)函數(shù)是定義到類上的。
第一種靜態(tài)函數(shù)的寫(xiě)法 :寫(xiě)在類上
(1)首先,定義一個(gè)簡(jiǎn)單的類,例如
function Person(name,age) { this.name=name; this.age;age; this.showName=function () { alert(this.name); } }
(2)定義一個(gè)寫(xiě)在類上的方法,Person.add --》(類.函數(shù))或者(類.屬性),例如
Person.add=function (x,y) { return x+y; }
(3)應(yīng)用
alert(Person.add(10,20));//結(jié)果為30
總結(jié)一下,該種定義方式有點(diǎn)類似于高級(jí)語(yǔ)言的靜態(tài)類,使用與高級(jí)語(yǔ)言的相同通過(guò)類直接調(diào)用。
第二種靜態(tài)函數(shù)的寫(xiě)法 :使用類中類的方式完成每一個(gè)對(duì)象全擁有當(dāng)前類中相同的屬性和函數(shù) 。注意: 類中類的方式是一次性賦值的
(1)類的定義格式如下
var cat=(function () { //私有靜態(tài)屬性 var AGE=1; function add(x,y) { return x+y; } return function () {//類中類 return返回的類中持有與上面類中相同的屬性與函數(shù) 則共同的AGE和add稱為靜態(tài)屬性和靜態(tài)函數(shù) this.AGE=AGE; this.add=function (x,y) { return add(x,y) } } })()//實(shí)例化cat,實(shí)質(zhì)是通過(guò)return實(shí)例化的
(2)應(yīng)用
alert(new cat().add(1,3))//4 alert(new cat().AGE)//1
總結(jié)一下:從上面的代碼格式中我們不難看出在一個(gè)類中定義有私有的屬性和方法,與一個(gè)返回可以初始化本類私有靜態(tài)屬性和方法的類,該類我們稱為類中類。當(dāng)我們實(shí)例化外層類時(shí)實(shí)質(zhì)上是通過(guò)該類內(nèi)部的類return實(shí)例化的。
封裝的優(yōu)點(diǎn):
(1)保護(hù)內(nèi)部數(shù)據(jù)完整性是封裝一大用處
(2)對(duì)象的重構(gòu)變得輕松,(如果沒(méi)有封裝你敢動(dòng)正在運(yùn)用的代碼嗎?) 答案肯定是不敢的。
(3)化模塊間的耦合
弊端:
(1)私有的方法會(huì)變得難以進(jìn)行單元測(cè)試
(2)使用封裝意味著與復(fù)雜的代碼打交道
(3)最大問(wèn)題封裝在JavaScript中很難實(shí)現(xiàn) 除非運(yùn)用自如,否則到處封裝,使測(cè)試變得困難。
以上只是學(xué)習(xí)的初步理解,不好還希望多多理解。
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- 詳解javascript常用工具類的封裝
- JS類的封裝及實(shí)現(xiàn)代碼
- javascript面向?qū)ο蟀b類Class封裝類庫(kù)剖析
- javascript封裝的sqlite操作類實(shí)例
- 常用JavaScript代碼提示公共類封裝
- js提取中文拼音首字母的封裝工具類
- 封裝了一個(gè)自動(dòng)生成漸變字的JS類(clip)
- JavaScript 面向?qū)ο蟪绦蛟O(shè)計(jì)詳解【類的創(chuàng)建、實(shí)例對(duì)象、構(gòu)造函數(shù)、原型等】
- JavaScript ES6 Class類實(shí)現(xiàn)原理詳解
- js定義類的方法示例【ES5與ES6】
- js類的繼承定義與用法分析
相關(guān)文章
js將當(dāng)前時(shí)間格式化為 年-月-日 時(shí):分:秒的實(shí)現(xiàn)代碼
這篇文章主要介紹了js將當(dāng)前時(shí)間格式化為 年-月-日 時(shí):分:秒主要是使用js的Date()對(duì)象,將系統(tǒng)當(dāng)前時(shí)間格式化為年-月-日 時(shí):分:秒,需要的朋友可以參考下2018-01-01js實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車模塊
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車模塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04echarts折線圖實(shí)現(xiàn)部分虛線部分實(shí)線效果的方法
在折線圖中,通常實(shí)線表示實(shí)際數(shù)據(jù),而虛線用于表示預(yù)測(cè)數(shù)據(jù),這篇文章主要介紹了echarts折線圖實(shí)現(xiàn)部分虛線部分實(shí)線效果的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09JavaScript實(shí)現(xiàn)飛舞的泡泡效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)飛舞的泡泡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02Javascript實(shí)現(xiàn)獲取窗口的大小和位置代碼分享
這篇文章主要分享了一段Javascript實(shí)現(xiàn)獲取窗口的大小和位置代碼,兼容性非常好,這里推薦給大家2014-12-12JS實(shí)現(xiàn)隊(duì)列的先進(jìn)先出功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)隊(duì)列的先進(jìn)先出功能,結(jié)合實(shí)例形式分析了基于JS的隊(duì)列初始化、賦值等相關(guān)操作技巧,需要的朋友可以參考下2017-05-05JS判斷當(dāng)前是否平板安卓并是否支持cordova方法的示例代碼
這篇文章主要介紹了JS判斷當(dāng)前是否平板安卓并是否支持cordova方法,pc和安卓平板共用一套代碼,平板的代碼用了cordova做了一個(gè)殼子嵌套如果用了cordova就不支持elementUI中的上傳功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08layui使用數(shù)據(jù)表格實(shí)現(xiàn)購(gòu)物車功能
這篇文章主要為大家詳細(xì)介紹了layui使用數(shù)據(jù)表格實(shí)現(xiàn)購(gòu)物車功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07JS常見(jiàn)面試試題總結(jié)【去重、遍歷、閉包、繼承等】
這篇文章主要介紹了JS常見(jiàn)面試試題,總結(jié)分析了javascript去重、遍歷、閉包、繼等相關(guān)算法與操作技巧,需要的朋友可以參考下2019-08-08