最近從朋友那邊白嫖了一只貓,說起這個擼貓洒琢,真是不得了秧秉,太有癮了,擼起來就停不下來衰抑,這可愛的小家伙喵喵喵的象迎,甄氏萌翻了。早上喂了早飯停士,鏟了屎就去上班了挖帘。
中午 12:00,我開始躁動不安了恋技,我家貓咋樣了,是不是餓著了逻族,是不是渴了蜻底。有沒有拆我家電視,有沒有撓我的沙發(fā),不行了薄辅,awsl要拂,我要知道我家貓在干啥。
- 我想知道我家貓在干啥
- 我不想打擾我家貓正常的生活
這不就是 AOP 嘛站楚,剛好最近正好工作有用到了 AOP脱惰,那我們不得不說一下什么是 AOP?
Aspect-oriented programming
面向切面編程窿春,旨在通過允許跨領(lǐng)域關(guān)注點的分離來提高模塊化拉一。通常呢是通過不修改代碼本身的情況下向現(xiàn)有代碼添加其他行為,目標(biāo)是一個切入點旧乞,切面蔚润,所以也就有了面向切面編程這個說法。值得一提的是尺栖,AOP 是一種編程規(guī)范嫡纠,并不是一種純粹的技術(shù),她只提供了定義延赌,具體實現(xiàn)還是有很多種的除盏,比較常見的就是裝飾器的形式。
function business() {
console.log('I will do some business!');
}
async function asyncBusiness() {
await new Promise(resolve => setTimeout(() => resolve('ohhhhhhhhhh'), 3000));
console.log('I will do some async business!');
}
function monitor(callback) {
return async function() {
console.log('monitor start');
const result = await callback.apply(this, arguments);
console.log('monitor end');
return result;
};
}
const monitorBusiness = monitor(business);
const monitorAsyncBusiness = monitor(asyncBusiness);
business();
monitorBusiness();
await asyncBusiness();
await monitorAsyncBusiness();
其實一個裝飾器就是這么簡單挫以,那么我們常見的@的形式來實現(xiàn)的裝飾器是什么樣的呢者蠕?@形式的裝飾器其實是利用了 Object.defineProperty。
Object.defineProperty
Object.defineProperty(obj, prop, descriptor)
obj
The object on which to define the property.prop
The name or Symbol of the property to be defined or modified.descriptor
The descriptor for the property being defined or modified.
詳細的內(nèi)容不在本期講解屡贺,如果有興趣蠢棱,請關(guān)注我們的公眾號 ihap 技術(shù)黑洞 ,之后我才會告訴你在 MDN 的鏈接是
不關(guān)注的你們就不知道了甩栈!
decorator
回到我們的裝飾器上泻仙,那么怎么寫一個在類里可以使用的裝飾器呢?
ok, 逼格 than 逼格量没,讓我們優(yōu)雅的在代碼里逼格一下玉转!
class WatchCat {
@log
eat() {
console.log('cat is eatting');
}
@log
drink() {
console.log('cat is drink');
}
}
function log(target) {
if (target.kind === 'method') {
const original = target.descriptor.value;
target.descriptor = {
...target.descriptor,
async value(...args) {
try {
console.log('I am watching my cat!');
const result = await original.apply(this, args);
console.log('I am finished watch my cat!');
return result;
} catch (err) {
console.error('sorry, my cat broken my monitor');
throw err;
}
},
};
}
return target;
}
const watchCat = new WatchCat();
watchCat.eat();
這樣,在我們對貓進行觀察的時候殴蹄,貓并沒有產(chǎn)生什么反應(yīng)究抓,還是在吃飯。
好了袭灯,我決定買個攝像頭來監(jiān)視我的貓每天究竟在干嘛
實際上它每天我不在的時候就在吃睡刺下,怪不得每天晚上都是這么精神。
好了稽荧,本次的肥少帶你擼貓之旅就到此結(jié)束了橘茉。不說了,問問客服能不能退貨,攝像頭完全沒有意義了畅卓。
自此感謝我們 ihap 技術(shù)黑洞 的鎮(zhèn)號之寵——芝麻擅腰!友情出演。
你們是不是以為沒了翁潘?哈哈哈哈哈哈哈趁冈,突然想起來忘記給你們講@log('ihap 技術(shù)黑洞')如果有參數(shù)的形式,要怎么寫了拜马。
function log(name) {
return target => {
if (target.kind === 'method') {
const original = target.descriptor.value;
target.descriptor = {
...target.descriptor,
async value(...args) {
try {
console.log(`${name} is watching my cat!`);
const result = await original.apply(this, args);
console.log(`${name} is finished watch my cat!`);
return result;
} catch (err) {
console.error('sorry, my cat broken my monitor');
throw err;
}
},
};
}
return target;
};
}
好了渗勘,真的沒有了,大家白白!
參考文獻:
https://stackoverflow.com/questions/8112111/is-aop-a-type-of-decorator-pattern
https://www.sitepoint.com/javascript-decorators-what-they-are/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty