ES7 Decorator初探

本文介绍了ES7中的装饰器(decorator),它是一种语法糖,可作用于类、类属性和方法,为其提供与业务逻辑无关功能的接口。详细阐述了装饰器作为自定义函数的参数和返回值,以及修饰类、类属性(或访问器)、类方法时的参数情况和不同返回值的影响。

decorator(装饰器)是ES7里面的一个语法糖,作用于类、类属性\方法,为它们提供一个实现与业务逻辑无关的功能的接口。

decorator为自定义函数

  • 参数:target、key、description
  • 返回值:newDescription/newTarget

修饰类

  • 参数target为类够构造函数,参数key、description为undefined
  • 若无返回值,则装饰后的类构造函数依旧为target
  • 若返回一个类构造函数,则以此作为构造函数
  • 若返回其他的值,则报错
const decorator = (target, key, description) => {
    console.log(target, key, description);
}

@decorator
class MyClass {
    _testNumber = 0;
};

const instance1 = new MyClass();
console.log(instance1 instanceof MyClass);

/* 输出结果
 *
 * ƒ MyClass() {
 *    _classCallCheck(this, MyClass);
 *
 *    this._testNumber = 0;
 * } undefined undefined
 *
 * true
 *
 */

 根据上面的例子可以看出,当装饰器作用于类的时候,参数key、description都是undefined;instance1是MyClass的实例。现在,让装饰器返回另外一个类看看结果如何:

class TestClass {
    test = 666;
}

const decorator = (target, key, description) => {
    return TestClass;
}

@decorator
class MyClass {
    _testNumber = 0;
};

const instance1 = new MyClass();
console.log(instance1.test);
console.log(instance1._testNumber);
console.log(instance1 instanceof MyClass);
console.log(instance1 instanceof TestClass);
console.log(MyClass === TestClass);


/* 输出结果
 *
 * 666
 * undefined
 * true
 * true
 * true
 *
 */

可以看出,装饰器返回一个新的类TestClass,并且创建的实例是TestClass的实例,而MyClass完全等于TestClass。

当然,我们可以在装饰器里面给target添加一些方法或者属性,返回target(或者不返回任何值),达到增强类构造函数的目的。

修饰类属性(或访问器)

  • 参数target为类的原型对象
  • 参数key为属性名
  • 参数description为该属性的描述符
  • 若无返回值,则该属性是构造函数实例的属性
  • 若返回一个描述符对象newDescription,则该属性与为构造函数原型的属性,为所有实例共享,其描述符为newDescription ;若newDescription不是一个完整的描述符对象,则缺少的配置属性会设置为默认值,多余的属性会被忽略掉
  • 若返回除对象外的其他值,报错
const decorator = (target, key, description) => {
    console.log(target, key, description);
}

class MyClass {
    
    @decorator
    _testNumber = 0;

};

const instance1 = new MyClass();
console.log(instance1._testNumber);
console.log(Object.getOwnPropertyDescriptor(instance1, 'getTestNumber'));

/* 输出结果
 *
 * {constructor: ƒ}constructor: ƒ MyClass()__proto__: Object "_testNumber" {enumerable: true, initializer: ƒ, configurable: false, writable: true}
 * 0
 * {value: 0, writable: true, enumerable: true, configurable: false}
 *
 */

 当装饰器作用于类属性时,target是MyCLass的原型,参数key是属性名“_testNumber”,没有返回值时,_testNumber依旧是instance的属性,它的描述符也没有改变。下面看看返回描述符的情况:

const decorator = (target, key, description) => {

    return {
        value: 2,
        writable: true,
        configuable: true,
        enumerable: true
    };

}

class MyClass {
    
    @decorator
    _testNumber = 0;

};

const instance1 = new MyClass();
console.log(instance1._testNumber);
console.log(Object.getOwnPropertyDescriptor(instance1, '_testNumber'));
console.log(Object.getOwnPropertyDescriptor(instance1.__proto__, '_testNumber'));


/* 输出结果
 *
 * 2
 * undefined
 * {value: 2, writable: true, enumerable: true, configurable: false}
 * 
 */

 当返回新的描述符时,_testNumber就不再是instance1的属性,而是MyClass原型的属性

修饰类方法

  • 参数target为类的原型对象
  • 参数key为属性名
  • 参数description为该属性的配置属性
  • 若无返回值,则该属性是构造函数原型的属性,为所有实例共享
  • 若返回一个描述符对象newDescription,则该属性与为构造函数原型的属性,为所有实例共享,其描述符为newDescription
  • 若返回除对象外的其他值,报错

修饰符修饰方法时与修饰属性差不多,这里将不再举例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值