摘要:用戶名不能為空密碼不能為空校驗未通過使用優化代碼返回的情況直接,不再執行后面的原函數用戶名不能為空密碼不能為空
本文是《JavaScript設計模式與開發實踐》的學習筆記,例子來源于書中,對于設計模式的看法,推薦看看本書作者的建議。
什么是裝飾者模式?給對象動態增加職責的方式成為裝飾者模式。
裝飾者模式能夠在不改變對象自身的基礎上,在運行程序期間給對象動態地添加職責。這是一種輕便靈活的做法,裝飾者是一種“即付即用”的方式,比如天冷了就多穿一件外套。
裝飾函數想要為函數添加一些功能,最簡單粗暴的方式就是直接改寫該函數,但是這是最差的辦法,直接違反了開放——封閉原則。
var a = function(){ alert(1) } // 改成 var a = function(){ alert(1) alert(2) }
很多時候我們不想碰原函數,也許原函數是其他同事編寫的,甚至在一個古老的項目中,這個函數的源代碼被隱藏在一個我們不愿觸碰的陰暗角落里。現在需要不改變源代碼的情況下,給函數增加功能。
我們通過保存原引用的方式改寫某個函數。
var a = function(){ alert(1) } var _a = a a = function(){ _a() alert(2) } a()
這是實際開發中很常見的一個做法,比如我們想給 window 綁定 onload 事件,但是又不確定這個事件是不是已經被其他人綁定過,為了避免覆蓋掉之前的 window.onload 函數中的行為,先保存 window.onload,把它放入新的 window.onload。
window.onload = function(){ alert(1) } var _onload = window.onload || function(){} window.onload = funtion(){ _onload() alert(2) }
這樣的代碼是符合封閉——開放原則,我們在增加新功能的時候確實沒有修改原來的代碼,但是這種方式存在兩個問題:
必須維護 _onload 這個中間變量,雖然看起來不起眼,但是如果函數裝飾鏈較長,或者需要裝飾的函數變多,這些中間變量的數量也會越來越多。
其實還遇到了 this 被劫持的問題,在 window.onload 的例子中沒有這個煩惱,因為調用 _onload 的時候 this 也指向 window,跟調用 window.onload 的時候一樣。
用 AOP 裝飾函數AOP(Aspect Oriented Programming)面向切面編程的主要作用是:把一些跟核心業務邏輯無關的功能抽離出來,這些跟業務邏輯無關的功能通常包括日志統計、安全控制、異常處理等。把這些功能抽離出來以后,再通過“動態織入”的方式摻入業務邏輯模塊中。這樣的好處首先是可以保持業務邏輯模塊的純凈和高內聚性,其次是可以很方便地復用日志統計等功能模塊。
首先給出 Function.prototype.before 和 Function.prototype.after 方法:
Function.prototype.before = function(beforefn){ // 保存原函數的引用 var _self = this // 返回包含原函數和新函數的“代理函數” return function(){ // 執行新函數,保證this不被劫持, // 新函數接受的參數也會被原封不動地傳入原函數, // 新函數在原函數之前執行 beforefn.apply(this,arguments) return _self.apply(this.arguments) } } Function.prototype.after = function(afterfn){ var _self = this return function(){ var ret = _self.apply(this,arguments) afterfn.apply(this,arguments) return ret } }
“代理函數”只是結構上像代理而已,并不承擔代理的職責(比如控制對象的訪問),它的工作是把請求分別轉發給新添加的函數和原函數,且負責保證它們的執行順序。
再回到 window.onload 的例子中,用 Function.prototype.after 來增加新事件:
window.onload = function(){ alert(1) } window.onload = (window.onload || function(){}).after(function(){ alert(2) }).after(function(){ alert(3) })AOP 的應用實例
(1)數據統計上報
showLogin 函數既要負責打開浮層,又要負責數據上報,兩個功能耦合在一個函數里,使用 AOP 分離:
(2) 插件式表單驗證
用戶名: 密碼:
formatSubmit 函數承擔了兩個職責,除了提交ajax請求,還要驗證用戶輸入的合法性。我們把校驗輸入的邏輯放到validata函數中,并約定當validata函數返回false的時候表示校驗未通過。
var validata = function(){ if ( username.value === "" ){ alert ( "用戶名不能為空" ); return false; } if ( password.value === "" ){ alert ( "密碼不能為空" ); return false; } } var formSubmit = function(){ if ( validata() === false ){ // 校驗未通過 return; } var param = { username: username.value, password: password.value } ajax( "http:// xxx.com/login", param ); } submitBtn.onclick = function(){ formSubmit(); }
使用AOP優化代碼
Function.prototype.before = function( beforefn ){ var __self = this; return function(){ if ( beforefn.apply( this, arguments ) === false ){ // beforefn 返回false 的情況直接return,不再執行后面的原函數 return; } return __self.apply( this, arguments ); } } var validata = function(){ if ( username.value === "" ){ alert ( "用戶名不能為空" ); return false; } if ( password.value === "" ){ alert ( "密碼不能為空" ); return false; } } var formSubmit = function(){ var param = { username: username.value, password: password.value } ajax( "http:// xxx.com/login", param ); } formSubmit = formSubmit.before( validata ); submitBtn.onclick = function(){ formSubmit(); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108950.html
摘要:聲明這個系列為閱讀設計模式與開發實踐曾探著一書的讀書筆記裝飾者模式的定義裝飾者模式能夠在不改變對象自身的基礎上,在程序運行期間給對像動態的添加職責。與繼承相比,裝飾者是一種更輕便靈活的做法。裝飾者模式的作用就是為對象動態的加入某些行為。 聲明:這個系列為閱讀《JavaScript設計模式與開發實踐》 ----曾探@著一書的讀書筆記 裝飾者模式的定義: 裝飾者(decorator)模式能...
摘要:下裝飾者的實現了解了裝飾者模式和的概念之后,我們寫一段能夠兼容的代碼來實現裝飾者模式原函數拍照片定義函數裝飾函數加濾鏡用裝飾函數裝飾原函數這樣我們就實現了抽離拍照與濾鏡邏輯,如果以后需要自動上傳功能,也可以通過函數來添加。 showImg(https://segmentfault.com/img/bVbueyz?w=852&h=356); 什么是裝飾者模式 當我們拍了一張照片準備發朋友...
摘要:設計模式裝飾者模式何為裝飾者,意思就是,在不影響對象主功能的情況下,再添加一些額外的功能,使對象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。 javascript設計模式 --- 裝飾者模式 何為裝飾者,意思就是,在不影響對象主功能的情況下,再添加一些額外的功能,使對象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。下面我們看看javascript里裝飾者模式 ...
摘要:裝飾者模式定義裝飾者模式能夠在不改變對象自身的基礎上,在程序運行期間給對像動態的添加職責。與繼承相比,裝飾者是一種更輕便靈活的做法。 裝飾者模式 定義 : 裝飾者(decorator)模式能夠在不改變對象自身的基礎上,在程序運行期間給對像動態的添加職責。與繼承相比,裝飾者是一種更輕便靈活的做法。 在不改變對象自身的基礎上,在程序運行期間給對象動態地添加一些額外職責 特點 : 可以動態的...
摘要:裝飾者模式裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對象,用于通過重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為以達到特定的目的。簡單的理解給對象動態添加職責的方式稱為裝飾著模式。 裝飾者模式 裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對象,用于通過重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為...
摘要:單體模式有以下優點用來劃分命名空間,減少全局變量數量。通常我們使用操作符創建單體模式的三種選擇,讓構造函數總返回最初的對象使用全局對象來存儲該實例不推薦,容易全局污染。實現該工廠模式并不困難,主要是要找到能夠穿件所需類型對象的構造函數。 介紹 最近開始給自己每周訂個學習任務,學習結果反饋為一篇文章的輸出,做好學習記錄。 這一周(02.25-03.03)我定的目標是《JavaScri...
閱讀 1449·2021-11-22 13:54
閱讀 4365·2021-09-22 15:56
閱讀 1822·2021-09-03 10:30
閱讀 1321·2021-09-03 10:30
閱讀 2089·2019-08-30 15:55
閱讀 1857·2019-08-30 14:13
閱讀 2063·2019-08-29 15:19
閱讀 2365·2019-08-28 18:13