参考资料:都2020年了,你还不会JavaScript 装饰器? 装饰器目前还是提案,新提案似乎还未出来,出来之后可能语法会发生改变,因此装饰器目前用的也不多。浏览器上还无法直接使用。不属于ES6

    target:被修饰的类
    name:类成员的名字
    descriptor:属性描述符,对象会将这个参数传给 Object.defineProperty

    1. // 语法
    2. const withSpeak = (targetClass) = {
    3. targetClass.speak = 'hello'
    4. }
    5. @withSpeak
    6. class Student{
    7. }
    8. cosnt stu = new Student()
    9. stu.speak // 'hello'
    10. const withLanguage = (language) => (targetClass) => {
    11. targetClass.prototype.language = language;
    12. }
    13. @withLanguage('Chinese')
    14. class Student {
    15. }
    16. const student = new Student();
    17. student.language; // 'Chinese'
    18. // 类属性装饰器
    19. function readonly(target, name, descriptor) {
    20. descriptor.writable = false;
    21. return descriptor;
    22. }
    23. class Person {
    24. @readonly name = 'person'
    25. }
    26. const person = new Person();
    27. person.name = 'tom';

    例子:time装饰器,用来统计一个函数的执行时间,以便于后期做一些性能优化:

    1. function time(target, name, descriptor) {
    2. const func = descriptor.value;
    3. if (typeof func === 'function') {
    4. descriptor.value = function(...args) {
    5. console.time();
    6. const results = func.apply(this, args);
    7. console.timeEnd();
    8. return results;
    9. }
    10. }
    11. }
    12. class Person {
    13. @time
    14. say() {
    15. console.log('hello')
    16. }
    17. }
    18. const person = new Person();
    19. person.say();

    节流throttle:

    1. const throttle = (time) => {
    2. let prev = new Date();
    3. return (target, name, descriptor) => {
    4. const func = descriptor.value;
    5. if (typeof func === 'function') {
    6. descriptor.value = function(...args) {
    7. const now = new Date();
    8. if (now - prev > wait) {
    9. fn.apply(this, args);
    10. prev = new Date();
    11. }
    12. }
    13. }
    14. }
    15. }
    16. // use
    17. class App extends React.Component {
    18. componentDidMount() {
    19. window.addEveneListener('scroll', this.scroll);
    20. }
    21. componentWillUnmount() {
    22. window.removeEveneListener('scroll', this.scroll);
    23. }
    24. @throttle(50)
    25. scroll() {}
    26. }

    防抖debounce:

    1. const debounce = (time) => {
    2. let timer;
    3. return (target, name, descriptor) => {
    4. const func = descriptor.value;
    5. if (typeof func === 'function') {
    6. descriptor.value = function(...args) {
    7. if(timer) clearTimeout(timer)
    8. timer = setTimeout(()=> {
    9. fn.apply(this, args)
    10. }, wait)
    11. }
    12. }
    13. }
    14. }

    core-decorators是一个封装了常用装饰器的 JS 库。