javascript單例模式與策略模式實(shí)例詳解
一、單例模式
1、概念
保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)
2、單例模式的實(shí)現(xiàn) -- 以創(chuàng)建div節(jié)點(diǎn)為例
var createDiv = (function(){
var instance;
var createDiv = function(html){
if(instance){
return instance
}
this.html = html;
this.init();
return instance = this;
};
createDiv.prototype.init = function(){
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div)
}
return createDiv;
})()
var a =new createDiv('one');
var b =new createDiv('two');
console.log(a===b); //true上述例子有缺點(diǎn):
(1)使用了匿名自執(zhí)行函數(shù),增加了函數(shù)復(fù)雜度
(2) createDiv函數(shù)做了兩件事情,一是創(chuàng)建對(duì)象,二是管理單例。違背了單一職責(zé)原則
改進(jìn)--》使用代理實(shí)現(xiàn)
//代理模式--改進(jìn)
//只負(fù)責(zé)創(chuàng)建div的一個(gè)類
var createDiv = function (html) {
this.html = html;
this.init();
};
createDiv.prototype.init = function () {
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div)
}
//引入代理類
var proxySingle = (function(){
var instance;
return function(html){
if(!instance){
instance = new createDiv(html)
}
return instance
}
})();
var a = new proxySingle('one');
var b = new proxySingle('two');
console.log(a === b); //true3、惰性單例(使用)
只在需要的時(shí)候才創(chuàng)建對(duì)象實(shí)例
聯(lián)系登陸功能的需求,登陸的彈框只會(huì)出現(xiàn)一次,在點(diǎn)擊點(diǎn)擊登陸按鈕的時(shí)候出現(xiàn)
兩種實(shí)現(xiàn)
(1)在頁面加載完成時(shí),創(chuàng)建好這個(gè)浮窗,浮窗一開始是隱藏狀態(tài),當(dāng)用戶點(diǎn)擊登錄的時(shí)候,它才開始顯示。缺點(diǎn):會(huì)白白浪費(fèi)一些DOM節(jié)點(diǎn)。
(2)當(dāng)用戶點(diǎn)擊登陸按鈕時(shí)才開始創(chuàng)建浮窗:代碼如下:
var createLoginer = function(){
var login = document.createElement("div");
login.innerHTML='登錄浮窗';
login.style.display = 'none';
document.body.appendChild(login);
return login
}
//點(diǎn)擊登陸按鈕
btn.onclick = function(){
var loginer = createLoginer();
loginer.style.display = 'block';
}現(xiàn)在惰性的目的達(dá)到了,但失去了單例的效果--》再次修改如下:
用一個(gè)變量判斷是否已經(jīng)創(chuàng)建過登錄浮窗
//創(chuàng)建登陸浮窗
var createLoginer = function () {
var login = document.createElement("div");
login.innerHTML = '登錄浮窗';
login.style.display = 'none';
document.body.appendChild(login);
return login
}
var loginer;
var getSingle = function (fn) {
return function () {
console.log(this)
return loginer || (loginer = fn.apply(this))
}
}
//createSingleLoginer接下來作為函數(shù)調(diào)用,所以getSingle得返回一個(gè)函數(shù),并且這個(gè)函數(shù)得返回登錄浮窗
var createSingleLoginer = getSingle(createLoginer);
//點(diǎn)擊登陸按鈕
var btn = document.getElementById("btn");
btn.onclick = function () {
var loginer = createSingleLoginer();
loginer.style.display = 'block';
}getSingle就是用來管理單例的
惰性單例:只有在合適的時(shí)候才創(chuàng)建對(duì)象,并只創(chuàng)建唯一的一個(gè)。把創(chuàng)建對(duì)象和管理單例的職責(zé)分布在不同的方法中,組合起來才能發(fā)揮真正的單例模式的威力。
二、策略模式
1、概念:
定義一系列的算法,把他們一個(gè)個(gè)封裝起來,并且使他們可以相互替換
2、實(shí)例
發(fā)年終獎(jiǎng),按照等級(jí)和各自的基礎(chǔ)工資進(jìn)行乘積運(yùn)算
var strage = {
S:function(salary){
return salary*4
},
A:function(salary){
return salary*3
},
B:function(salary){
return salary*2
}
}
var calculateBounus = function(level,salary){
return strage[level](salary)
};
console.log(calculateBounus('S',2000)) //8000
console.log(calculateBounus('A',2000)) //60003、策略模式用來封裝算法,更廣義的使用,表單驗(yàn)證登錄算法
把校驗(yàn)方式封裝成策略對(duì)象
var validatorFunc = function () {
var validator = new Validator();
validator.add(loginForm.userName, "isEmpty", '用戶名不能為空')
validator.add(loginForm.passWord, "minLength:6", '密碼長(zhǎng)度不能少于6位')
validator.add(loginForm.phone, "phoneValidator", '手機(jī)號(hào)碼格式錯(cuò)誤')
var errMsg = validator.start();
return errMsg
}
var loginForm = document.getElementById("login")
function login() {
var errMsg = validatorFunc();
if (errMsg) {
alert(errMsg);
return false; //阻止表單提交
}
}
var Validator = function () {
//緩存校驗(yàn)規(guī)則
this.cache = [];
}
Validator.prototype.add = function (dom, rule, err) {
var ary = rule.split(':');
this.cache.push(function () {
var strategy = ary.shift();
ary.unshift(dom.value);
ary.push(err)
return loginStrage[strategy].apply(dom, ary)
})
}
Validator.prototype.start = function () {
for (var i = 0; i < this.cache.length; i++) {
var err = this.cache[i]()
if (err) {
alert(err)
}
}
}運(yùn)行頁面:
- js單例模式的兩種方案
- JS實(shí)現(xiàn)單例模式的6種方案匯總
- javascript 單例模式演示代碼 javascript面向?qū)ο缶幊?/a>
- JavaScript的單例模式 (singleton in Javascript)
- 輕松掌握J(rèn)avaScript單例模式
- [js高手之路]單例模式實(shí)現(xiàn)模態(tài)框的示例
- JavaScript設(shè)計(jì)模式之策略模式詳解
- javascript設(shè)計(jì)模式--策略模式之輸入驗(yàn)證
- JavaScript設(shè)計(jì)模式之策略模式實(shí)例
- 學(xué)習(xí)JavaScript設(shè)計(jì)模式之策略模式
- 學(xué)習(xí)JavaScript設(shè)計(jì)模式(策略模式)
相關(guān)文章
原生JavaScript實(shí)現(xiàn)Ajax異步請(qǐng)求
ajax現(xiàn)在是一種非常流行的技術(shù),現(xiàn)在雖然可以利用JQuery或者一些第三方插件甚至微軟提供的一些控件可以方面的實(shí)現(xiàn)ajax功能,但是明白其原理也是非常重要的,下面是來使用純javascript實(shí)現(xiàn)獲取服務(wù)器端的功能來展示如何使用純javascript實(shí)現(xiàn)ajax功能,以弄清其原理.2017-11-11
Javascript實(shí)現(xiàn)貪吃蛇小游戲(含詳細(xì)注釋)
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
javascript時(shí)間戳和日期字符串相互轉(zhuǎn)換代碼(超簡(jiǎn)單)
下面小編就為大家?guī)硪黄猨avascript時(shí)間戳和日期字符串相互轉(zhuǎn)換代碼(超簡(jiǎn)單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06
Javascript中數(shù)組sort和reverse用法分析
這篇文章主要介紹了Javascript中數(shù)組sort和reverse用法,實(shí)例分析了sort和reverse使用時(shí)的注意事項(xiàng)與相關(guān)技巧,具有不錯(cuò)的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12

