前言
今天在學(xué)習(xí)中對(duì)于裝飾器感覺比較陌生,于是百度查了一下Decorator的用法,特意在此記錄一下。
須知
由于目前并不直接支持Decorator,因此需要先安裝babel-plugin-transform-decorators-legacy
yarn add babel-plugin-transform-decorators-legacy babel-core babel-polyfill --dev
同時(shí)修改.babelrc文件
{
"plugins": ["transform-decorators-legacy"]
}
-
簡(jiǎn)介
裝飾器(Decorator)是一種與類(class)相關(guān)的語(yǔ)法,用來(lái)注釋或修改類和類方法。許多面向?qū)ο蟮恼Z(yǔ)言都有這項(xiàng)功能,目前有一個(gè)提案將其引入了 ECMAScript。
裝飾器是一種函數(shù),寫成@ + 函數(shù)名。它可以放在類和類方法的定義前面。
-
類的裝飾
裝飾器可以用來(lái)修飾整個(gè)類
@test
class Boy{
}
function test(target){
target.age=10
}
console.log(Boy.age)//10
上面是給class加靜態(tài)屬性,同樣可以給class加實(shí)例屬性,可以通過(guò)目標(biāo)類的prototype對(duì)象操作。
@test
class Boy{
}
function test(target){
target.prototype.age=10
}
const luck=new Boy();
console.log(luck.age)//10
如果參數(shù)不夠用,可以在裝飾器外層再封裝一層函數(shù)
@test(11)
class Boy{
}
function test(age){
return function(target){
target.prototype.age=age;
}
}
const luck=new Boy();
console.log(luck.age)//11
-
裝飾方法
class Boy{
@log
add(a,b){
return a+b
}
}
function log(target,name,descriptor){
let oldValue=descriptor.value;
descriptor.value=function(){
console.log(`calling ${name} with`,arguments);
return oldValue.apply(this,arguments)
}
return descriptor
}
const math =new Boy();
console.log(math.add(2,3))
//calling add with [Arguments] { '0': 2, '1': 3 }
//5
裝飾器第一個(gè)參數(shù)是類的原型對(duì)象,上例是Boy.prototype,裝飾器的本意是要“裝飾”類的實(shí)例,但是這個(gè)時(shí)候?qū)嵗€沒生成,所以只能去裝飾原型(這不同于類的裝飾,那種情況時(shí)target參數(shù)指的是類本身);第二個(gè)參數(shù)是所要裝飾的屬性名,第三個(gè)參數(shù)是該屬性的描述對(duì)象。
-
Mixin
在裝飾器的基礎(chǔ)上,可以實(shí)現(xiàn)Mixin模式。將一個(gè)對(duì)象混入另外一個(gè)對(duì)象。
const Foo={
foo(){
console.log('foo')
}
}
function mixins(list){
return function (target) {
Object.assign(target.prototype,list);
};
}
@mixins(Foo)
class MyClass {}
let obj = new MyClass();
obj.foo()