Rumah > Artikel > hujung hadapan web > Apakah penghias dalam es6
Dalam ES6, Decorator ialah sintaks yang berkaitan dengan kelas, digunakan untuk menganotasi atau mengubah suai kelas dan kaedah kelas; sebelum definisi kelas dan kaedah kelas. Terdapat dua jenis penghias: penghias kelas dan penghias kaedah kelas.
Persekitaran pengendalian tutorial ini: sistem Windows 7, ECMAScript versi 6, komputer Dell G3.
Corak Penghias membenarkan menambah fungsi baharu pada objek sedia ada tanpa mengubah strukturnya. Corak reka bentuk jenis ini ialah corak struktur, yang bertindak sebagai pembalut di sekeliling kelas sedia ada.
Corak ini mencipta kelas hiasan untuk membalut kelas asal dan menyediakan kefungsian tambahan sambil mengekalkan integriti tandatangan kaedah kelas.
Dalam ES6, penghias (Penghias) ialah sintaks berkaitan kelas yang digunakan untuk menganotasi atau mengubah suai kelas dan kaedah kelas.
Penghias sebenarnya adalah fungsi, biasanya diletakkan di hadapan kelas dan kaedah kelas.
Perubahan kelakuan kelas oleh penghias berlaku apabila kod disusun, bukan pada masa jalankan; intipati penghias ialah fungsi yang dilaksanakan semasa penyusunan
Penghias boleh digunakan untuk menghiasi Seluruh kelas
@decorateClass class Example { @decorateMethods method(){} }
在上面的代码中使用了两个装饰器,其中 @decorateClass()
装饰器用在类本身,用于增加或修改类的功能;@decorateMethods()
装饰器用在类的方法,用于注释或修改类方法。
装饰器只能用于类和类的方法,不能用于函数,因为存在函数提升。
装饰器只能用于类和类的方法,下面我们分别看下两种类型的装饰器的使用
1、类装饰器
类装饰器用来装饰整个类
类装饰器的参数
target: 类本身,也相当于是 类的构造函数:Class.prototype.constructor。
@decorateClass class Example { //... } function decorateClass(target) { target.isTestClass = true }
如上面代码中,装饰器 @decorateClass 修改了 Example 整个类的行为,为 Example 类添加了静态属性 isTestClass。装饰器就是一个函数,decorateClass 函数中的参数 target 就是 Example 类本身,也相当于是类的构造函数 Example.prototype.constructor.
装饰器传参
上面实现的装饰器在使用时是不能传入参数的,如果想要在使用装饰器是传入参数,可以在装饰器外面再封装一层函数
@decorateClass(true) class Example { //... } function decorateClass(isTestClass) { return function(target) { target.isTestClass = isTestClass } }
上面代码中实现的装饰器在使用时可以传递参数,这样就可以根据不同的场景来修改装饰器的行为。
实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。
class MyReactComponent extends React.Component {} export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
有了装饰器,就可以改写上面的代码。
@connect(mapStateToProps, mapDispatchToProps) export default class MyReactComponent extends React.Component {}
2、类方法装饰器
类方法装饰器用来装饰类的方法
类方法装饰器的参数
target:
装饰器修饰的类方法是静态方法:target 为类的构造函数
装饰器修饰的类方法是实例方法:target 为类的原型对象
method:被修饰的类方法的名称
descriptor:被修饰成员的属性描述符
// descriptor对象原来的值如下 { value: specifiedFunction, enumerable: false, configurable: true, writable: true };
class Example { @log instanceMethod() { } @log static staticMethod() { } } function log(target, methodName, descriptor) { const oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments); return oldValue.apply(this, arguments); }; return descriptor; }
如上面代码中,装饰器 @log 分别装饰了实例方法 instanceMethod 和 静态方法 staticMethod。@log 装饰器的作用是在执行原始的操作之前,执行 console.log 来输出日志。
类方法装饰器传参
上面实现的装饰器在使用时是不能传入参数的,如果想要在使用装饰器是传入参数,可以在装饰器外面再封装一层函数
class Example { @log(1) instanceMethod() { } @log(2) static staticMethod() { } } function log(id) { return (target, methodName, descriptor) => { const oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments, `this id is ${id}`); return oldValue.apply(this, arguments); }; return descriptor; } }
上面代码中实现的装饰器在使用时可以传递参数,这样就可以根据不同的场景来修改装饰器的行为。
如果在一个类中,同时使用装饰器修饰类和类的方法,那么装饰器的执行顺序是:先执行类方法的装饰器,再执行类装饰器。
如果同一个类或同一个类方法有多个装饰器,会像剥洋葱一样,先从外到内进入,然后由内到外执行。
// 类装饰器 function decoratorClass(id){ console.log('decoratorClass evaluated', id); return (target) => { // target 类的构造函数 console.log('target 类的构造函数:',target) console.log('decoratorClass executed', id); } } // 方法装饰器 function decoratorMethods(id){ console.log('decoratorMethods evaluated', id); return (target, property, descriptor) => { // target 代表 // process.nextTick((() => { target.abc = 123 console.log('method target',target) // })) console.log('decoratorMethods executed', id); } } @decoratorClass(1) @decoratorClass(2) class Example { @decoratorMethods(1) @decoratorMethods(2) method(){} } /** 输入日志 **/ // decoratorMethods evaluated 1 // decoratorMethods evaluated 2 // method target Example { abc: 123 } // decoratorMethods executed 2 // method target Example { abc: 123 } // decoratorMethods executed 1 // decoratorClass evaluated 1 // decoratorClass evaluated 2 // target 类的构造函数: [Function: Example] // decoratorClass executed 2 // target 类的构造函数: [Function: Example] // decoratorClass executed 1
如上面代码中,会先执行类方法的装饰器 @decoratorMethods(1) 和 @decoratorMethods(2),执行完后再执行类装饰器 @decoratorClass(1) 和 @decoratorClass(2)
上面代码中的类方法装饰器中,外层装饰器 @decoratorMethods(1) 先进入,但是内层装饰器 @decoratorMethods(2) 先执行。类装饰器同理。
function log(target, name, descriptor) { var oldValue = descriptor.value; descriptor.value = function () { console.log(`Calling "${name}" with`, arguments); return oldValue.apply(null, arguments); } return descriptor; } // 日志应用 class Maths { @log add(a, b) { return a + b; } } const math = new Maths(); // passed parameters should get logged now math.add(2, 4);
【相关推荐:javascript视频教程、web前端】
Atas ialah kandungan terperinci Apakah penghias dalam es6. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!