javascript單例模式與策略模式實例詳解
一、單例模式
1、概念
保證一個類僅有一個實例,并提供一個訪問它的全局訪問點
2、單例模式的實現(xiàn) -- 以創(chuàng)建div節(jié)點為例
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
上述例子有缺點:
(1)使用了匿名自執(zhí)行函數(shù),增加了函數(shù)復雜度
(2) createDiv函數(shù)做了兩件事情,一是創(chuàng)建對象,二是管理單例。違背了單一職責原則
改進--》使用代理實現(xiàn)
//代理模式--改進 //只負責創(chuàng)建div的一個類 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); //true
3、惰性單例(使用)
只在需要的時候才創(chuàng)建對象實例
聯(lián)系登陸功能的需求,登陸的彈框只會出現(xiàn)一次,在點擊點擊登陸按鈕的時候出現(xiàn)
兩種實現(xiàn)
(1)在頁面加載完成時,創(chuàng)建好這個浮窗,浮窗一開始是隱藏狀態(tài),當用戶點擊登錄的時候,它才開始顯示。缺點:會白白浪費一些DOM節(jié)點。
(2)當用戶點擊登陸按鈕時才開始創(chuàng)建浮窗:代碼如下:
var createLoginer = function(){ var login = document.createElement("div"); login.innerHTML='登錄浮窗'; login.style.display = 'none'; document.body.appendChild(login); return login } //點擊登陸按鈕 btn.onclick = function(){ var loginer = createLoginer(); loginer.style.display = 'block'; }
現(xiàn)在惰性的目的達到了,但失去了單例的效果--》再次修改如下:
用一個變量判斷是否已經(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得返回一個函數(shù),并且這個函數(shù)得返回登錄浮窗 var createSingleLoginer = getSingle(createLoginer); //點擊登陸按鈕 var btn = document.getElementById("btn"); btn.onclick = function () { var loginer = createSingleLoginer(); loginer.style.display = 'block'; }
getSingle就是用來管理單例的
惰性單例:只有在合適的時候才創(chuàng)建對象,并只創(chuàng)建唯一的一個。把創(chuàng)建對象和管理單例的職責分布在不同的方法中,組合起來才能發(fā)揮真正的單例模式的威力。
二、策略模式
1、概念:
定義一系列的算法,把他們一個個封裝起來,并且使他們可以相互替換
2、實例
發(fā)年終獎,按照等級和各自的基礎工資進行乘積運算
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)) //6000
3、策略模式用來封裝算法,更廣義的使用,表單驗證登錄算法
把校驗方式封裝成策略對象
var validatorFunc = function () { var validator = new Validator(); validator.add(loginForm.userName, "isEmpty", '用戶名不能為空') validator.add(loginForm.passWord, "minLength:6", '密碼長度不能少于6位') validator.add(loginForm.phone, "phoneValidator", '手機號碼格式錯誤') 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 () { //緩存校驗規(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) } } }
運行頁面:
相關文章
Javascript實現(xiàn)貪吃蛇小游戲(含詳細注釋)
這篇文章主要為大家詳細介紹了Javascript實現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-10-10javascript時間戳和日期字符串相互轉(zhuǎn)換代碼(超簡單)
下面小編就為大家?guī)硪黄猨avascript時間戳和日期字符串相互轉(zhuǎn)換代碼(超簡單)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06Javascript中數(shù)組sort和reverse用法分析
這篇文章主要介紹了Javascript中數(shù)組sort和reverse用法,實例分析了sort和reverse使用時的注意事項與相關技巧,具有不錯的參考借鑒價值,需要的朋友可以參考下2014-12-12