您好,登錄后才能下訂單哦!
這篇文章主要介紹了es6中語法糖Decorator怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
Decorator
(修飾器/裝飾器)是es6提出的語法糖,用于修改類的行為。不過目前主流瀏覽器都沒有很好的支持,我們需要用babel來轉換為瀏覽器能識別的語言。
1.修飾類
(1) 基礎用法
@testable class MyClass{} function testable(target){ target.isTestable=true } console.log(MyClass.isTestable) // true
貼一下babel轉換后的代碼,
var _class; let MyClass = testable(_class = class MyClass {}) || _class; function testable(target) { target.isTestable = true; }
也可以在prototype上修改屬性,也可以為修飾器添加多個參數。
@testable(false) class MyAnotherClass{ } function testable(status){ return target=>{target.prototype.isTestable=status} } console.log('MyClass.isTestable',MyAnotherClass.prototype.isTestable) // false
當然我們通過修飾器,把某個對象的方法添加到目標類的實例上,注意要在類的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) 應用
在React App
的開發中,使用redux
通常需要react-redux
中的connect
方法,將兩者結合在一起。通常的寫法是:
class MyReactComponent extends React.Component {} export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
如果使用decorator
,代碼可讀性更高了一些。
@connect(mapStateToProps, mapDispatchToProps) export default class MyReactComponent extends React.Component {}
2.修飾方法
(1).基礎用法
// 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為不可重新定義,默認值為true enumerable:false,//對象屬性是否可通過for-in循環,flase為不可循環,默認值為true writable:false,//對象屬性是否可修改,flase為不可修改,默認值為true value:'xiaoming' //對象屬性的默認值,默認值為undefined });
對應到descriptor為下面四個屬性:
{ value: specifiedFunction, enumerable: false, configurable: true, writable: true };
(3). 應用
我們開始寫一個@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作用是在返回結果前,打印函數名和其參數,起到輸出日至的作用。上面的程序運行后,控制臺將輸出:
calling add with {"0":1,"1":2}
(4). 多個修飾器
良好命名的修飾器可以起到簡潔注釋的作用,如下:
class Example { @readonly @enumable method(){} }
多個修飾器的執行順序是由外向內進入;再由內向外執行。
class Example { @decorator(1) @decorator(2) method(){} } function decorator(id){ console.log('id is ',id) return (target,property,descriptor)=>console.log('executed',id) }
控制臺輸出
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" ] }
執行編譯后的文件
因為我們為了測試,沒必要非得放在瀏覽器里看了,可以用node執行babel轉換后的文件。直接運行yarn start
。
// package.json "scripts": { "build": "babel ./decorator -d lib", "start":"yarn build && node ./lib/index.js" },
感謝你能夠認真閱讀完這篇文章,希望小編分享的“es6中語法糖Decorator怎么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。