溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在JavaScript中實(shí)現(xiàn)AOP

發(fā)布時(shí)間:2021-06-01 18:13:42 來源:億速云 閱讀:233 作者:Leah 欄目:web開發(fā)

本篇文章為大家展示了怎么在JavaScript中實(shí)現(xiàn)AOP,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

1. 簡(jiǎn)介

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

怎么在JavaScript中實(shí)現(xiàn)AOP

2. 基礎(chǔ)實(shí)現(xiàn)

使用過java spring的同學(xué)一定知道,其內(nèi)分為三種通知,before(前置通知)、after(后置通知)、around(環(huán)繞通知)。
下面我們分別在js調(diào)用方法時(shí)實(shí)現(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("測(cè)試前置通知");

// 調(diào)用結(jié)果
// before: 1557047939699
// 原型函數(shù): 測(cè)試前置通知

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("測(cè)試后置通知");

// 調(diào)用結(jié)果
// 原型函數(shù): 測(cè)試前置通知
// after: 1557047997647

around(環(huán)繞通知)

在方法執(zhí)行前后分別執(zhí)行

// 利用前面的before、after方法實(shí)現(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進(jìn)行轉(zhuǎn)換,當(dāng)AOP與修飾器結(jié)合后,又會(huì)給我們帶來什么呢?

日志記錄

通過AOP與修飾器的結(jié)合會(huì)很方便的進(jìn)行日志的記錄或者函數(shù)執(zhí)行時(shí)間的記錄

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) {
 // 校驗(yàn)方法,假設(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),請(qǐng)看下面的例子

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>
 }
}

上述內(nèi)容就是怎么在JavaScript中實(shí)現(xiàn)AOP,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI