字段或属性装饰器是在ES7(ECMAScript 2016)中提出的,但是在ES9(ECMAScript 2018)中得到了进一步的更新和改进。一个装饰器是一个特殊的函数,可以用来修改或者增强类或对象的属性或方法。
装饰器的语法
装饰器的语法非常简单,只需要在要修饰的属性或方法前面加上特殊的注释语法即可:
class MyClass { @myDecorator myProperty = 'Hello'; @myOtherDecorator myMethod() { console.log('World'); } }
在上面的代码中,可以看到 @myDecorator
和 @myOtherDecorator
就是装饰器。
装饰器的应用
装饰器可以用来进行一些有用的操作,例如:
日志记录
可以使用装饰器来记录某些属性或方法的调用日志。例如:
function log(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args) { console.log(`Calling ${key} with arguments`, ...args); const result = originalMethod.apply(this, args); console.log(`Result of ${key} is`, result); return result; } return descriptor; } class MyClass { @log myMethod(a, b) { return a + b; } } const instance = new MyClass(); instance.myMethod(2, 3);
在上面的代码中, log
装饰器用来记录 myMethod
方法的调用以及其返回值。在这个例子中,当 myMethod
调用时,它会输出一些日志信息,如下所示:
Calling myMethod with arguments 2 3 Result of myMethod is 5
计算属性值
使用装饰器可以实现一些属性的计算值,例如:
function computed(target, key, descriptor) { const originalMethod = descriptor.get; descriptor.get = function() { return originalMethod.call(this) + ' World'; } return descriptor; } class MyClass { @computed get myProperty() { return 'Hello'; } } const instance = new MyClass(); console.log(instance.myProperty);
在上面的代码中, computed
装饰器用来计算 myProperty
属性的值。在这个例子中,当访问 myProperty
的时候,它会自动增加一个 "World" 后缀。
验证参数
使用装饰器可以对方法的参数进行验证,例如:
function validate(target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(a, b) { if(a < 0 || b < 0) { throw new Error('Invalid arguments'); } return originalMethod.apply(this, arguments); } return descriptor; } class MyClass { @validate myMethod(a, b) { return a + b; } } const instance = new MyClass(); console.log(instance.myMethod(2, 3)); // 5 console.log(instance.myMethod(-2, 3)); // Error: Invalid arguments
在上面的代码中, validate
装饰器用来验证 myMethod
方法的参数是否有效。在这个例子中,如果方法的参数不是正数,它会抛出一个错误。
总结
装饰器是一个非常强大的特性,可以方便地实现许多有用的功能,并且可以使代码更加清晰和可读性更好。如果您有兴趣进一步了解装饰器,可以查阅相关的文档和教程学习。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a3bad0add4f0e0ffbe0db7