什么是修飾器
修飾器(Decorator)是javascript/339279.html">ES7的一個提案,它的出現能解決兩個問題:
用法也很簡單,就是在類或方法的上面加一個@符,在vue in typescript中經常用到
以上的兩個用處可能不太明白,沒關系,我們開始第一個例子
例子1:修飾類
@setPropclass User {}function setProp(target) { target.age = 30}console.log(User.age)
這個例子要表達的是對User類使用setProp這個方法進行修飾,用來增加User類中age的屬性,setProp方法會接收3個參數,我們現在接觸第一個,target代表User類本身。
例子2:修飾類(自定義參數值)
@setProp(20)class User {}function setProp(value) { return function (target) { target.age = value }}console.log(User.age)
此例和上面功能基本一致,唯一差別在于值是參考修飾函數傳過來的
例子2:修飾方法
class User { @readonly getName() { return 'Hello World' }}// readonly修飾函數,對方法進行只讀操作function readonly(target, name, descriptor) { descriptor.writable = false return descriptor}let u = new User()// 嘗試修改函數,在控制臺會報錯u.getName = () => { return 'I will override'}
上例中,我們對User類中的getName方法使用readonly修飾器進行修飾,使得方法不能被修改。第一個參數我們已經知道了,參數name為方法名,也就是readonly,參數descriptor是個啥東西呢,看到這行descriptor.writable = false,我們大家猜的也差不多了,這三個參數對應的就是Object.defineProperty的三個參數,我們來看一下:
我們設置descriptor.writable = false就是讓函數不可以被修改,如果我們寫成
descriptor.value = 'function (){ console.log('Hello decorator') }'
那么,輸出就是Hello World了,而是Hello decorator,是不是已經意識到修飾器的好處了?,F在我們來看看實際工作中,我們用到修飾器的例子
實際應用1:日志管理
在用webpack打包時,我們經常需要好多步驟,比如第一步讀取package.json文件,第二步處理該文件,第三步加載webpack.base.js文件,第四步進行打包...為了直觀,我們經常在每一步打印一些日志文件,比如這步都干了些什么事,很明顯打印日志的操作和業務代碼根本就一點關系沒有,我們不應該把日志和業務摻和在一起,這樣使用修飾器就是避免這個問題,以下為代碼:
class Pack { @log('讀取package.json文件') step1() { // do something... // 沒有修飾器之前,我們通常把console.log放到這里寫 // 放到函數里面寫會有兩個壞處 // 1.console和業務無關,會破壞函數單一性原則 // 2.如果要刪除所有的console,那我們只能深入到每一個方法中 } @log('合并webpack配置文件') step2() { // do something... }}function log(value) { return function (target, name, descriptor) { // 在這里,我們還可以拿到函數的參數,打印更加詳細的信息 console.log(value) }}let pack = new Pack()pack.step1()pack.step2()
實際應用2:檢查登錄
這個例子在實際的開發中常用得到,我們一些操作前,必須得判斷用戶是否登錄,比較點贊、結算、發送彈幕...按照之前的寫法,我們必須在每一個方法中判斷用戶的登錄情況,然后再進行業務的操作,很顯然前置條件和業務又混到了一起,用修飾器,就可以完美的解決這一問題,代碼如下:
class User { // 獲取已登錄用戶的用戶信息 @checkLogin getUserInfo() { /** * 之前,我們都會這么寫: * if(checkLogin()) { * // 業務代碼 * } * 這段代碼會在每一個需要登錄的方法中執行 * 還是上面的問題,執行的前提和業務又混到了一起 */ console.log('獲取已登錄用戶的用戶信息') } // 發送消息 @checkLogin sendMsg() { console.log('發送消息') }}// 檢查用戶是否登錄,如果沒有登錄,就跳轉到登錄頁面function checkLogin(target, name, descriptor) { let method = descriptor.value // 模擬判斷條件 let isLogin = true descriptor.value = function (...args) { if (isLogin) { method.apply(this, args) } else { console.log('沒有登錄,即將跳轉到登錄頁面...') } }}let u = new User()u.getUserInfo()u.sendMsg()
結語
以上只是修飾器的基本應用,只要我們掌握了原理,在實際的工作中,要思考自己的應用場景,只要我們涉及需要在執行前做一些處理的應用,不管是修改函數的參數值,還是增加屬性,還是執行的先決條件,我們都可以使用修飾器,這種編程的方式,就是面向切面編程
源碼以及使用方法,請移步GitHub
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。
新聞熱點
疑難解答