詳解es6超好用的語法糖Decorator
Decorator(修飾器/裝飾器)是es6提出的語法糖,用于修改類的行為。不過目前主流瀏覽器都沒有很好的支持,我們需要用babel來轉(zhuǎn)換為瀏覽器能識(shí)別的語言。在這篇文章中將介紹decorator的基礎(chǔ)用法和一些應(yīng)用實(shí)例。
1.修飾類
(1) 基礎(chǔ)用法
@testable
class MyClass{}
function testable(target){
target.isTestable=true
}
console.log(MyClass.isTestable) // true
貼一下babel轉(zhuǎn)換后的代碼,
var _class;
let MyClass = testable(_class = class MyClass {}) || _class;
function testable(target) {
target.isTestable = true;
}
也可以在prototype上修改屬性,也可以為修飾器添加多個(gè)參數(shù)。
@testable(false)
class MyAnotherClass{
}
function testable(status){
return target=>{target.prototype.isTestable=status}
}
console.log('MyClass.isTestable',MyAnotherClass.prototype.isTestable) // false
當(dāng)然我們通過修飾器,把某個(gè)對(duì)象的方法添加到目標(biāo)類的實(shí)例上,注意要在類的prototype上添加。
const foo={isTestable:true}
function testable(...list){
return target=>{Object.assign(target.prototype,...list)}
}
@testable(foo)
class MyAnotherClass{}
const obj=new MyAnotherClass()
console.log('MyClass.isTestable',obj.isTestable) // true
(2) 應(yīng)用
在React App的開發(fā)中,使用redux通常需要react-redux中的connect方法,將兩者結(jié)合在一起。通常的寫法是:
class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
如果使用decorator,代碼可讀性更高了一些。
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}
2.修飾方法
(1).基礎(chǔ)用法
// target:在方法中的target指向類的prototype
function readonly(target,key,descriptor){
descriptor.writable=false
return descriptor
}
class MyClass{
@readonly
print(){console.log(`a:${this.a}`)}
}
(2).js中Object的屬性
var person = {}
Object.defineProperty(person,'name',{
configurable:false,//能否使用delete、能否需改屬性特性、或能否修改訪問器屬性、,false為不可重新定義,默認(rèn)值為true
enumerable:false,//對(duì)象屬性是否可通過for-in循環(huán),flase為不可循環(huán),默認(rèn)值為true
writable:false,//對(duì)象屬性是否可修改,flase為不可修改,默認(rèn)值為true
value:'xiaoming' //對(duì)象屬性的默認(rèn)值,默認(rèn)值為undefined
});
對(duì)應(yīng)到descriptor為下面四個(gè)屬性:
{
value: specifiedFunction,
enumerable: false,
configurable: true,
writable: true
};
(3). 應(yīng)用
我們開始寫一個(gè)@log修飾器,可以輸出日志:
class Math{
@log
add(a,b){
return a+b
}
}
const math=new Math()
math.add(1,2)
function log(target,name,descriptor){
const oldValue=descriptor.value
descriptor.value=function(){
console.log(`calling ${name} with ${JSON.stringify(arguments)}`)
return oldValue.apply(this,arguments)
}
return descriptor
}
上面的代碼中,@log作用是在返回結(jié)果前,打印函數(shù)名和其參數(shù),起到輸出日至的作用。上面的程序運(yùn)行后,控制臺(tái)將輸出:
calling add with {"0":1,"1":2}
(4). 多個(gè)修飾器
良好命名的修飾器可以起到簡潔注釋的作用,如下:
class Example {
@readonly
@enumable
method(){}
}
多個(gè)修飾器的執(zhí)行順序是由外向內(nèi)進(jìn)入;再由內(nèi)向外執(zhí)行。
class Example {
@decorator(1)
@decorator(2)
method(){}
}
function decorator(id){
console.log('id is ',id)
return (target,property,descriptor)=>console.log('executed',id)
}
控制臺(tái)輸出
id is 1
id is 2
executed 2
executed 1
附錄:babel配置
babel插件transform-decorators還沒有正式版,我們可以用transform-decorators-legacy。
安裝babel
yarn add babel-plugin-transform-decorators-legacy babel-preset-es2017
配置.babelrc
{
"presets": ["es2017"],
"plugins":[
"transform-decorators-legacy"
]
}
執(zhí)行編譯后的文件
因?yàn)槲覀優(yōu)榱藴y(cè)試,沒必要非得放在瀏覽器里看了,可以用node執(zhí)行babel轉(zhuǎn)換后的文件。直接運(yùn)行yarn start。
// package.json
"scripts": {
"build": "babel ./decorator -d lib",
"start":"yarn build && node ./lib/index.js"
},
參考鏈接
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
利用JavaScript做數(shù)獨(dú)的完整實(shí)現(xiàn)過程
數(shù)獨(dú)游戲是在一個(gè)9*9的方格中進(jìn)行填數(shù)字的游戲,需要滿足的規(guī)則是每行每列和每個(gè)子九宮格都是1~9的不重復(fù)數(shù)字,下面這篇文章主要給大家介紹了關(guān)于如何利用JavaScript做數(shù)獨(dú)的相關(guān)資料,需要的朋友可以參考下2021-09-09
不用AI也能實(shí)現(xiàn)的文字自動(dòng)播報(bào)(SpeechSynthesis文本實(shí)例合成)
SpeechSynthesis是HTML5的一個(gè)新特性,基于SpeechSynthesis可以實(shí)現(xiàn)在客戶瀏覽器端進(jìn)行動(dòng)態(tài)文本的語音合成播放,這篇文章主要介紹了不用AI也能實(shí)現(xiàn)的文字自動(dòng)播報(bào)(SpeechSynthesis文本實(shí)例合成),需要的朋友可以參考下2023-03-03
JS函數(shù)節(jié)流和函數(shù)防抖問題分析
這篇文章主要介紹了JS函數(shù)節(jié)流和函數(shù)防抖問題分析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-12-12
微信小程序 仿美團(tuán)分類菜單 swiper分類菜單
本文主要介紹了微信小程序仿美團(tuán)分類菜單(swiper分類菜單)的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04
原生Js頁面滾動(dòng)延遲加載圖片實(shí)現(xiàn)原理及過程
頁面滾動(dòng)加載事件,獲取元素在頁面里的top值根據(jù)滾動(dòng)條的位置判斷何時(shí)顯示圖片;獲取元素集合 加載過的圖片從集合里刪除,具體實(shí)現(xiàn)如下,感興趣的朋友各位可以參考下哈2013-06-06
JavaScript基于自定義函數(shù)判斷變量類型的實(shí)現(xiàn)方法
這篇文章主要介紹了JavaScript基于自定義函數(shù)判斷變量類型的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了javascript判斷變量類型的自定義函數(shù)定義與使用方法,并針對(duì)不同瀏覽器給出了相關(guān)的分析與說明,需要的朋友可以參考下2016-11-11
微信小程序錄音實(shí)現(xiàn)功能并上傳(使用node解析接收)
在我們的日常開發(fā)中經(jīng)常會(huì)遇到錄音功能,并上傳到服務(wù)器,今天小編給大家分享微信小程序錄音功能實(shí)現(xiàn)并上傳錄音文件,使用node解析接收,需要的朋友可以參考下2020-02-02

