JavaScript中AOP的實現(xiàn)與應(yīng)用
1. 簡介
AOP (Aspect Oriented Programming) ,意為:面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。AOP是OOP的延續(xù),是函數(shù)式編程的一種衍生,利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。

2. 基礎(chǔ)實現(xiàn)
使用過java spring的同學(xué)一定知道,其內(nèi)分為三種通知,before(前置通知)、after(后置通知)、around(環(huán)繞通知)。
下面我們分別在js調(diào)用方法時實現(xiàn)這三種通知:
before(前置通知)
顧名思義,就是在函數(shù)調(diào)用前執(zhí)行
Function.prototype.before = function (beforefun) {
var _orgin = this; // 保存原函數(shù)引用
return function () { // 返回包含了原函數(shù)和新函數(shù)的"代理函數(shù)"
beforefun.apply(this, arguments); // 執(zhí)行新函數(shù),修正this
return _orgin.apply(this, arguments); // 執(zhí)行原函數(shù)
}
};
var originFun = function(val){
console.log('原型函數(shù): '+val);
}
var newFun = originFun.before(function(){
// 傳入函數(shù)調(diào)用前處理方法
console.log('before: ' + new Date().getTime())
})
newFun("測試前置通知");
// 調(diào)用結(jié)果
// before: 1557047939699
// 原型函數(shù): 測試前置通知
after(后置通知)
與before正相反,在函數(shù)調(diào)用后執(zhí)行
Function.prototype.after = function (afterfun) {
var _orgin = this; // 保存原函數(shù)引用
return function () { // 返回包含了原函數(shù)和新函數(shù)的"代理函數(shù)"
var ret = _orgin.apply(this, arguments); // 執(zhí)行原函數(shù)
afterfun.apply(this, arguments); // 執(zhí)行新函數(shù),修正this
return ret;
}
};
var originFun = function(val){
console.log('原型函數(shù): '+val);
}
var newFun = originFun.after(function(){
// 傳入函數(shù)調(diào)用前處理方法
console.log('after: ' + new Date().getTime())
})
newFun("測試后置通知");
// 調(diào)用結(jié)果
// 原型函數(shù): 測試前置通知
// after: 1557047997647
around(環(huán)繞通知)
在方法執(zhí)行前后分別執(zhí)行
// 利用前面的before、after方法實現(xiàn)
Function.prototype.around = function(beforeFun, afterFun) {
var _orgin = this;
return function() {
return _orgin.before(beforeFun).after(afterFun).apply(this, arguments);
}
}
3. AOP遇到修飾器
JS在ES7的提案中終于增加了修飾器(Decorator)函數(shù),它是用來修改類的行為,但是現(xiàn)在瀏覽器都不支持,需要使用Babel進行轉(zhuǎn)換,當AOP與修飾器結(jié)合后,又會給我們帶來什么呢?
日志記錄
通過AOP與修飾器的結(jié)合會很方便的進行日志的記錄或者函數(shù)執(zhí)行時間的記錄
class Person {
@log
say(nick) {
return `hi ${nick}`;
}
}
function log(target, name, decriptor){
var _origin = descriptor.value;
descriptor.value = function(){
console.log(`Calling ${name} with `, argumants);
return _origin.apply(null, arguments);
};
return descriptor;
}
var person = new Person();
person.say('小明');
判斷用戶登錄狀態(tài)
class User {
@checkLogin
getUserInfo() {
console.log('獲取用戶信息')
}
}
// 檢查用戶是否登錄
function checkLogin(target, name, descriptor) {
let method = descriptor.value
descriptor.value = function (...args) {
// 校驗方法,假設(shè)這里可以獲取到用戶名/密碼
if (validate(args)) {
method.apply(this, args)
} else {
console.log('沒有登錄,即將跳轉(zhuǎn)到登錄頁面...')
}
}
}
let user = new User()
user.getUserInfo()
4. React中的AOP
在react中使用AOP思想的典型就是高階組件(HOC),請看下面的例子
function HOCComp(WrappedComponent){
return class HOC extends Component {
render(){
const newProps = {param: 'HOC'};
return <div>
<WrappedComponent {...this.props} {...newProps}/>
</div>
}
}
}
@HOCComp
class OriginComponent extends Component {
render(){
return <div>這是原始組件{this.props.param}</div>
}
}
上面例子中在HOCComp中定義新的props,并傳入子組件中。我們也可以對OriginComponent組件中的一些props進行加工,或?qū)riginComponent外層進行再次包裝。從而不必去修改內(nèi)部組件,保持了功能上的解耦。
5. 總結(jié)
AOP思想在框架及項目中使用的很多,包括React高階組件、日志記錄、登錄驗證、redux中間件等。在開發(fā)中應(yīng)該與OOP相輔相成,共同提高軟件的健壯性及可維護性。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
參考資料
- 使用AOP改善javascript代碼
- Springboot 使用 JSR 303 對 Controller 控制層校驗及 Service 服務(wù)層 AOP 校驗 使用消息資源文件對消息國際化
- javascript AOP 實現(xiàn)ajax回調(diào)函數(shù)使用比較方便
- 初識SmartJS - AOP三劍客
- JavaScript實現(xiàn)AOP詳解(面向切面編程,裝飾者模式)
- Javascript aop(面向切面編程)之a(chǎn)round(環(huán)繞)分析
- JavaScript之AOP編程實例
- JavaScript AOP編程實例
- 關(guān)于AOP在JS中的實現(xiàn)與應(yīng)用詳解
相關(guān)文章
JavaScript canvas實現(xiàn)環(huán)形漸變進度條
這篇文章主要為大家詳細介紹了JavaScript canvas實現(xiàn)環(huán)形漸變進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
利用JScript中運算符"||"和"&&"的特殊特性實現(xiàn)代碼精
利用JScript中運算符"||"和"&&"的特殊特性實現(xiàn)代碼精簡...2007-03-03
js判斷iframe內(nèi)的網(wǎng)頁是否滾動到底部觸發(fā)事件
這篇文章主要介紹了js判斷iframe內(nèi)的網(wǎng)頁是否滾動到底部觸發(fā)事件,需要的朋友可以參考下2014-03-03

