es6中什么是装饰器

发布时间:2022-05-17 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了es6中什么是装饰器脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

在es6中,装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法;装饰器其实就是一个编译时执行的函数,语法“@函数名”,通常放在类和类方法的定义前面。装饰器有两种:类装饰器和类方法装饰器。

es6中什么是装饰器

本教程操作环境:windows7系统、ecmascript 6版、Dell G3脑。

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

ES6 装饰器

在 ES6 中,装饰器(Decorator)是一种与类相关的语法,用来注释或修改类和类方法。

装饰器其实就是一个函数,通常放在类和类方法的前面。

装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时;装饰器的本质就是编译时执行的函数

装饰器可以用来装饰整个类

@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) 先执行。类装饰器同理。

利用装饰器实现AOP切面编程

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前端】

以上就是es6中什么是装饰器的详细内容,更多请关注脚本宝典其它相关文章

脚本宝典总结

以上是脚本宝典为你收集整理的es6中什么是装饰器全部内容,希望文章能够帮你解决es6中什么是装饰器所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:es6