javascript常用的設(shè)計(jì)模式
js最好是一種面向?qū)ο蟮恼Z(yǔ)言。它的出現(xiàn)時(shí)比較遲的。但是它是目前最火的腳本語(yǔ)言。而且,隨著近期的微信商城等頁(yè)面的興起,相信程序員和互聯(lián)網(wǎng)的從業(yè)者都知道了js正在勢(shì)頭上了。
那么,如果你想要在前端這條路上走得更遠(yuǎn),設(shè)計(jì)模式就必須要懂。下面介紹幾種常見(jiàn)的設(shè)計(jì)模式。
一、單例模式
單例模式也稱作為單子模式,更多的也叫做單體模式。為軟件設(shè)計(jì)中較為簡(jiǎn)單但是最為常用的一種設(shè)計(jì)模式。 在JavaScript里,實(shí)現(xiàn)單例的方式有很多種,其中最簡(jiǎn)單的一個(gè)方式是使用對(duì)象字面量的方法,其字面量里可以包含大量的屬性和方法:
var mySingleton = {
property1: "something",
property2: "something else",
method1: function () {
console.log('hello world');
}};
如果以后要擴(kuò)展該對(duì)象,你可以添加自己的私有成員和方法,然后使用閉包在其內(nèi)部封裝這些變量和函數(shù)聲明。只暴露你想暴露的public成員和方法,樣例代碼如下:
var mySingleton = function () {
/* 這里聲明私有變量和方法 */
var privateVariable = 'something private';
function showPrivate() {
console.log(privateVariable);
}
/* 公有變量和方法(可以訪問(wèn)私有變量和方法) */
return {
publicMethod: function () {
showPrivate();
},
publicVar: 'the public can see this!'
};
};
var single = mySingleton();
single.publicMethod(); // 輸出 'something private'
console.log(single.publicVar); // 輸出 'the public can see this!'
上面的代碼很不錯(cuò)了,但如果我們想做到只有在使用的時(shí)候才初始化,那該如何做呢?為了節(jié)約資源的目的,我們可以另外一個(gè)構(gòu)造函數(shù)里來(lái)初始化這些代碼,如下:
var Singleton = (function () {
var instantiated;
function init() {
/*這里定義單例代碼*/
return {
publicMethod: function () {
console.log('hello world');
},
publicProperty: 'test'
};
}
return {
getInstance: function () {
if (!instantiated) {
instantiated = init();
}
return instantiated;
}
};
})();
/*調(diào)用公有的方法來(lái)獲取實(shí)例:*/
Singleton.getInstance().publicMethod();
二、工廠模式
工廠模式是由一個(gè)方法來(lái)決定到底要?jiǎng)?chuàng)建哪個(gè)類的實(shí)例, 而這些實(shí)例經(jīng)常都擁有相同的接口. 這種模式主要用在所實(shí)例化的類型在編譯期并不能確定, 而是在執(zhí)行期決定的情況。 說(shuō)的通俗點(diǎn),就像公司茶水間的飲料機(jī),要咖啡還是牛奶取決于你按哪個(gè)按鈕。
實(shí)例:
function A( name ){
this.name = name;
}
function ObjectFactory(){
var obj = {},
Constructor = Array.prototype.shift.call( arguments );
obj.__proto__ = typeof Constructor .prototype === 'number' ? Object.prototype
: Constructor .prototype;
var ret = Constructor.apply( obj, arguments );
return typeof ret === 'object' ? ret : obj;
}
var a = ObjectFactory( A, 'svenzeng' );
alert ( a.name ); //svenzeng
這段代碼來(lái)自es5的new和構(gòu)造器的相關(guān)說(shuō)明, 可以看到,所謂的new, 本身只是一個(gè)對(duì)象的復(fù)制和改寫(xiě)過(guò)程, 而具體會(huì)生成什么是由調(diào)用ObjectFactory時(shí)傳進(jìn)去的參數(shù)所決定的。
三、 適配模式
簡(jiǎn)單的說(shuō),適配模式主要是為了解決一些接口不兼容產(chǎn)生的解決方法。借助于適配器我們可以在不修改這些不兼容接口的情況下給使用者提供統(tǒng)一的包裝過(guò)的適配接口。表面上又感覺(jué)和之前的門面模式比較像,均是對(duì)其他對(duì)象或者接口進(jìn)行包裝再呈現(xiàn),而適配器模式偏向的是解決兼容性問(wèn)題,門面模式則偏向方便性為原則。
比如一個(gè)簡(jiǎn)單的學(xué)生查詢學(xué)科成績(jī)的方法:
function selectScore( name, id, course_id ){
// arguments 姓名 學(xué)號(hào) 課程id
...
}
當(dāng)我需要一個(gè)班級(jí)某門學(xué)科的整體成績(jī)列表,而我手上只有每個(gè)學(xué)生如下的數(shù)據(jù)
[
{ name: 'lily', studentID: '0911' },
{ name: 'suny', studentID: '0912' },
...
]
我需要查詢 英語(yǔ) 其課程ID為 101,那么對(duì)于該任務(wù),寫(xiě)一個(gè)適配器方式是很恰當(dāng)不過(guò)的
function selectEnglishScore( stutentObj ){
selectScore( stutentObj.name, stutentObj.studentID , 101);
}
這是一個(gè)最簡(jiǎn)單的關(guān)于適配器來(lái)處理參數(shù)方面兼容的形式。 其實(shí)簡(jiǎn)單的來(lái)說(shuō),適配器模式意義上很簡(jiǎn)單 - 適配,解決兼容問(wèn)題。
例子二,比如你覺(jué)得jquery里邊的$選擇器需要改成$id才能和你的項(xiàng)目搭配,那么這時(shí)候?qū)懸粋€(gè)方法,將$轉(zhuǎn)換成$id就很輕松了。如下:
$id = function( id ){
return jQuery( '#' + id )[0];
}
四、外觀模式
外觀模式(門面模式),是一種相對(duì)簡(jiǎn)單而又無(wú)處不在的模式。外觀模式提供一個(gè)高層接口,這個(gè)接口使得客戶端或子系統(tǒng)更加方便調(diào)用。 用一段再簡(jiǎn)單不過(guò)的代碼來(lái)表示:
var getName = function(){
return ''svenzeng"
}
var getSex = function(){
return 'man'
}
如果你需要分別調(diào)用getName和getSex函數(shù). 那可以用一個(gè)更高層的接口getUserInfo來(lái)調(diào)用.:
var getUserInfo = function(){
var info = a() + b();
return info;
}
也許你會(huì)問(wèn)為什么一開(kāi)始不把getName和getSex的代碼寫(xiě)到一起, 比如這樣:
var getNameAndSex = function(){
return 'svenzeng" + "man";
}
答案是顯而易見(jiàn)的,飯?zhí)玫某床藥煾挡粫?huì)因?yàn)槟泐A(yù)定了一份燒鴨和一份白菜就把這兩樣菜炒在一個(gè)鍋里。他更愿意給你提供一個(gè)燒鴨飯?zhí)撞汀M瑯釉诔绦蛟O(shè)計(jì)中,我們需要保證函數(shù)或者對(duì)象盡可能的處在一個(gè)合理粒度,畢竟不是每個(gè)人喜歡吃燒鴨的同時(shí)又剛好喜歡吃白菜。 外觀模式還有一個(gè)好處是可以對(duì)用戶隱藏真正的實(shí)現(xiàn)細(xì)節(jié),用戶只關(guān)心最高層的接口。比如在燒鴨飯?zhí)撞偷墓适轮校悴⒉魂P(guān)心師傅是先做燒鴨還是先炒白菜,你也不關(guān)心那只鴨子是在哪里成長(zhǎng)的。
最后寫(xiě)個(gè)我們都用過(guò)的外觀模式例子:
var stopEvent = function( e ){ //同時(shí)阻止事件默認(rèn)行為和冒泡
e.stopPropagation();
e.preventDefault();
}
好了,今天的額設(shè)計(jì)模式就先到這里。如果大家想要了解更多的設(shè)計(jì)模式可以去湯姆大叔的博客欣賞哦。還有,這里的很多的設(shè)計(jì)模式其實(shí)都是將解決問(wèn)題的方法細(xì)化了的說(shuō)法,如果去看一下prototype或者jquery都會(huì)知道,其實(shí)里邊的代碼很多都用到了設(shè)計(jì)模式的。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- JS設(shè)計(jì)模式之責(zé)任鏈模式實(shí)例詳解
- JavaScript編程設(shè)計(jì)模式之構(gòu)造器模式實(shí)例分析
- JS設(shè)計(jì)模式之?dāng)?shù)據(jù)訪問(wèn)對(duì)象模式的實(shí)例講解
- JavaScript設(shè)計(jì)模式之代理模式詳解
- JavaScript設(shè)計(jì)模式之單例模式詳解
- JavaScript設(shè)計(jì)模式之策略模式詳解
- JavaScript 設(shè)計(jì)模式 安全沙箱模式
- JavaScript設(shè)計(jì)模式之觀察者模式(發(fā)布者-訂閱者模式)
- javascript設(shè)計(jì)模式之解釋器模式詳解
- JavaScript設(shè)計(jì)模式之調(diào)停者模式實(shí)例詳解
相關(guān)文章
JavaScript Math對(duì)象和調(diào)試程序的方法分析
這篇文章主要介紹了JavaScript Math對(duì)象和調(diào)試程序的方法,結(jié)合實(shí)例形式分析了javascript中Math對(duì)象生成隨機(jī)數(shù)以及使用alert()、console.log()函數(shù)進(jìn)行錯(cuò)誤調(diào)試相關(guān)操作技巧,需要的朋友可以參考下2019-05-05
javascript下拉框選項(xiàng)單擊事件的例子分享
這篇文章主要分享了一些javascript下拉框選項(xiàng)單擊事件的例子,以及在例子中遇到的問(wèn)題的解決方法,十分實(shí)用,推薦給小伙伴們參考下。2015-03-03
javascript 靜態(tài)對(duì)象和構(gòu)造函數(shù)的使用和公私問(wèn)題
靜態(tài)對(duì)象和構(gòu)造函數(shù)的使用區(qū)別 平常我們會(huì)經(jīng)常使用JSON形式,或者var obj=function(){}亦或function(){}這么幾種對(duì)象的構(gòu)建辦法,有時(shí)會(huì)認(rèn)為這是等價(jià)的辦法,然而他們還有不同。2010-03-03
JavaScript實(shí)現(xiàn)點(diǎn)擊單選按鈕改變輸入框中文本域內(nèi)容的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊單選按鈕改變輸入框中文本域內(nèi)容的方法,涉及javascript單選按鈕控制頁(yè)面元素樣式的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
JS如何通過(guò)視頻鏈接獲取視頻時(shí)長(zhǎng)
這篇文章主要介紹了JS如何通過(guò)視頻鏈接獲取視頻時(shí)長(zhǎng),這個(gè)函數(shù)用提供的URL創(chuàng)建一個(gè)新的Video元素,并在loadedmetadata事件被觸發(fā)時(shí)解析一個(gè)帶有視頻持續(xù)時(shí)間的Promise,感興趣的朋友跟隨小編一起看看吧2024-06-06
JS+CSS實(shí)現(xiàn)的簡(jiǎn)單折疊展開(kāi)多級(jí)菜單效果
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)的簡(jiǎn)單折疊展開(kāi)多級(jí)菜單效果,涉及JavaScript頁(yè)面元素的遍歷及動(dòng)態(tài)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
微信小程序?qū)崿F(xiàn)文字長(zhǎng)按復(fù)制與一鍵復(fù)制功能全過(guò)程
微信小程序開(kāi)發(fā)是依托微信的,所以他的代碼是嵌入在微信的原始代碼之中的,這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)文字長(zhǎng)按復(fù)制與一鍵復(fù)制功能的相關(guān)資料,需要的朋友可以參考下2023-03-03
JavaScript裝飾器的實(shí)現(xiàn)原理詳解
最近在使用TS+Vue的開(kāi)發(fā)模式,發(fā)現(xiàn)項(xiàng)目中大量使用了裝飾器,看得我手足無(wú)措,今天特意研究一下實(shí)現(xiàn)原理,方便自己理解這塊知識(shí)點(diǎn),有需要的小伙伴也可以參考一下2022-10-10

