日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ECMAScript Decorators---装饰器

發(fā)布時(shí)間:2023/12/2 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ECMAScript Decorators---装饰器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ECMAScript Decorators---裝飾器

Decorators是什么

  • Decorators可以改變類方法和類實(shí)例字段的屬性和行為,使我們可以靈活地使用更簡(jiǎn)單的語(yǔ)法動(dòng)態(tài)實(shí)現(xiàn)這些內(nèi)容,是非侵入式的。---舉例,你給手機(jī)添加一個(gè)外殼罷了,并不影響手機(jī)原有的通話、充電等功能

應(yīng)用場(chǎng)景

  • Decorators的經(jīng)典的應(yīng)用是AOP編程,比如“日志系統(tǒng)”,日志系統(tǒng)的作用是記錄系統(tǒng)的行為操作,它在不影響原有系統(tǒng)的功能的基礎(chǔ)上增加記錄環(huán)節(jié)
  • 更加抽象的理解,可以理解為給數(shù)據(jù)流做一層filter,因此 AOP 的典型應(yīng)用包括安全檢查、緩存、調(diào)試、持久化等等。

原理

  • Decorators的本質(zhì)是利用了ES5的Object.defineProperty屬性,這三個(gè)參數(shù)其實(shí)是和Object.defineProperty參數(shù)一致的,因此不能更改
  • object 必需。要在其上添加或修改屬性的對(duì)象 這可能是一個(gè)本機(jī)JavaScript對(duì)象(即用戶定義的對(duì)象或內(nèi)置對(duì)象)或 DOM 對(duì)象。
  • propertyname必需。一個(gè)包含屬性名稱的字符串
  • descriptor 必需。 屬性描述符。它可以針對(duì)數(shù)據(jù)屬性或訪問(wèn)器屬性。
  • 舉例說(shuō)明
var myObj = {myPropOne: 1,myPropTwo: 2 }; // modify property descriptor Object.defineProperty( myObj, 'myPropOne', {writable: false, // 是否允許該屬性值更改enumerable: false, // 是否允許key被枚舉,話句話說(shuō)for in 或者Object.keys() 不會(huì)輸出keyconfigurable: false// 目標(biāo)屬性是否可以被刪除或是否可以再次修改特性 } );

應(yīng)用舉例

  • 類方法 @readonly
  • class User {constructor( firstname, lastName ) {this.firstname = firstname;this.lastName = lastName;}@readonlygetFullName() {return this.firstname ' ' this.lastName;} } // create instance let user = new User( 'John', 'Doe' ); console.log( user.getFullName() );// 某天我不小心重寫(xiě)了這個(gè)方法 User.prototype.getFullName = function() {return 'HACKED!'; }// 輸出 HACKED! 與預(yù)期不符,怎么避免此類情況發(fā)生// 方法1 這是最好的解決方案么?修飾器登場(chǎng) Object.defineProperty( User.prototype, 'getFullName', {writable: false });// 將此方法添加到修飾方法getFullName上 function readonly( target, property, descriptor ) {descriptor.writable = false;return descriptor; }
  • 類方法 @log日志打印
  • function log( logMessage ) {// return decorator functionreturn function ( target, property, descriptor ) {// save original value, which is method (function)let originalMethod = descriptor.value;// replace method implementationdescriptor.value = function( ...args ) {console.log( '[LOG]', logMessage );// here, call original method// `this` points to the instancereturn originalMethod.call( this, ...args );};return descriptor;} } class User {constructor( firstname, lastName ) {this.firstname = firstname;this.lastName = lastName;}@log('calling getFullName method on User class')getFullName() {return this.firstname ' ' this.lastName;} } var user = new User( 'John', 'Doe' ); console.log( user.getFullName() );
  • 類的屬性 大小寫(xiě)轉(zhuǎn)換
  • // 解釋:descriptor.initializer函數(shù)由Babel內(nèi)部使用來(lái)創(chuàng)建對(duì)象屬性的屬性描述符的值 function toCase( CASE = 'lower' ) {return function ( target, name, descriptor ) {let initValue = descriptor.initializer();descriptor.initializer = function(){return ( CASE == 'lower' ) ? initValue.toLowerCase() : initValue.toUpperCase();}return descriptor;} } class User {@toCase( 'upper' )firstName = 'default_first_name';lastName = 'default_last_name';constructor( firstName, lastName ) {if( firstName ) this.firstName = firstName;if( lastName ) this.lastName = lastName;}getFullName() {return this.firstName ' ' this.lastName;} } console.log( new User() );
  • 類裝飾器
  • function withLoginStatus( UserRef ) {return class extends UserRef {constructor( ...args ) {super( ...args );this.isLoggedIn = false;}setLoggedIn() {this.isLoggedIn = true;}} } @withLoginStatus class User {constructor( firstName, lastName ) {this.firstName = firstName;this.lastName = lastName;} } let user = new User( 'John', 'Doe' ); console.log( 'Before ===> ', user ); // set logged in user.setLoggedIn(); console.log( 'After ===> ', user );

    babel 裝換

    • 在線轉(zhuǎn)換鏈接(如無(wú)法打開(kāi)網(wǎng)頁(yè)需翻墻)
    • 構(gòu)建babel裝換
    1、創(chuàng)建項(xiàng)目文件 2、命令行進(jìn)入該項(xiàng)目目錄 npm init 3、npm install babel-core babel-plugin-transform-decorators 4、安裝 npm install babel-plugin-transform-decorators-legacy --save-dev 5、.babelrc添加 { "plugins": [ "transform-decorators-legacy"] }

    參考鏈接

    • ECMAScript Decorators---裝飾器
    • ES7 Decorator 裝飾者模式
    • 阮一峰---修飾器

    總結(jié)

    以上是生活随笔為你收集整理的ECMAScript Decorators---装饰器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。