初聽面向切面編程時, 一頭霧水, 什麼是面向切面, 只據說過面向對象(OOP), 面向過程(PO), 函數式編程(FP), 面向切面 ? 面向的難道是某一個面?前端
面向搜索引擎後才瞭解到, 面向切面是一種編程範式(Aspect Oriented Programming), 簡寫 AOP, 特色是與原有邏輯解耦, 無侵入.ios
在後端開發工做中, 常見使用的場景是 斷點調試/打印日誌/...,編程
而在前端開發工做中, 應用場景比較靈活多變, 能夠是在一次表單提交中, 在表單提交前做表單驗證(前置), 或在表單提交後做數據刷新/頁面跳轉/Cookie 刷新等 (後置), 也能夠在提交的同時做數據埋點(橫向), 或是打印日誌。。。
對於外部的新加入的邏輯, 爲了避免破壞原有的業務邏輯, 咱們就可使用 AOP 去組織代碼, 分離 [業務邏輯] 與 [瑣碎事務]axios
const before = function(fn, action) { return function(...args) { action.apply(this, args); const res = fn.apply(this, args); return { res, params: args }; }; };
const after = function(fn, action) { return function(...args) { let res = fn.apply(this, args); action.apply(this, args); return { res, params: args }; }; };
const throwing = function(fn, action) { let ret = { res: undefined, params: undefined }; return function(...args) { try { const res = fn.apply(this, args); return (ret = { res, params: args }); } catch (err) { action.apply(this, args); return (ret = { res: err, params: args }); } }; };
const round = function(fn, actionBefore, actionAfter) { return function(...args) { actionBefore.apply(this, args); const res = fn.apply(this, args); actionAfter.apply(this, args); return { res, params: args }; }; };
const request = config => axios.request(config); const ButtonClickFn = function () { ...do something } document.querySelector('#submit').click = before(ButtonClickFn, () => { request({ url: 'http://your_upload_log_url', method: 'GET', params: { TYPE: 'BUTTON_CLICK', POSITION: '' } }); });
const originRequest = config => axios.request(config); const wrapperedRequest = throwing(originRequest, function() { ...異常上報 });
實際上除了使用高階函數的方法實現, 咱們還可使用 ES7 的裝飾器/Ojbect.defineProperty 實現, 或基於原型鏈去實現後端