ES7 装饰器理解 (转载)

还有一篇:https://www.jianshu.com/p/2c2fb890f01c

 

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
若返回除对象外的其他值,报错
修饰符修饰方法时与修饰属性差不多,这里将不再举例子
---------------------
作者:paper_crane
来源:CSDN
原文:https://blog.csdn.net/zhangwx6/article/details/82261038
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2018-11-01 21:31  刘昭廷  阅读(137)  评论(0编辑  收藏  举报