安装
// cmd
cnpm i -g typescript
配置
// cmd
tsc --init
将tsconfig.json的experimentalDecorators
设为true, 启动实验阶段的装饰器功能
代码
新建文件test.ts
// 装饰器调用顺序
// 属性装饰器>方法参数装饰器>方法装饰器>静态属性装饰器>静态方法装饰器>类装饰器
// 定义:相同装饰器按右边>左边 ,下面>上面
// 执行:相同装饰器按左边>右边 ,上面>下面
/**
* 属性装饰器
* @param targetPrototype 构造函数的原型
* @param propName 属性名称
*/
function propDecorator1(targetPrototype: any, propName: string) {
console.log('属性装饰器1:', targetPrototype, propName);
}
function propDecorator2(params: string) {
console.log('属性装饰器2 before:', params);
return function (targetPrototype: any, propName: string) {
// targetPrototype[propName]是在原型链上查找实例属性,永远为undefined
console.log('属性装饰器2:', targetPrototype, propName, targetPrototype[propName]);
targetPrototype[propName] = "会在原型上面添加该属性并赋值,不是实例对象";
};
}
function propDecorator3(params: string) {
console.log('属性装饰器3 before:', params);
return function (targetPrototype: any, propName: string) {
console.log('属性装饰器3:', targetPrototype, propName);
};
}
/**
* 方法装饰器
* @param targetPrototype 构造函数的原型
* @param methodName 方法名称
* @param descr 方法的描述
*/
function methodDecorator1(targetPrototype: any, methodName: string, descriptor: PropertyDescriptor) {
console.log('方法装饰器1:', targetPrototype, methodName, descriptor);
}
let methodDecorator2: any = function (params: string) {
console.log('方法装饰器2 before:', params);
return function (targetPrototype: any, methodName: string, descriptor: PropertyDescriptor) {
console.log('方法装饰器2:', targetPrototype, methodName, descriptor);
};
};
let methodDecorator3: any = function (params: string) {
console.log('方法装饰器3 before:', params);
return function (targetPrototype: any, methodName: string, descriptor: PropertyDescriptor) {
console.log('方法装饰器3:', targetPrototype, methodName, descriptor);
let originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
args = args.map(item => item += " test");
return originalMethod.apply(this, args);
};
return descriptor;
};
};
/**
* 方法参数装饰器
* @param targetPrototype 构造函数的原型
* @param methodName 方法名称
* @param paramIndex 参数在arguments中的下标
*/
function paramDecorator1(targetPrototype: any, methodName: string, paramIndex: number) {
console.log('方法参数装饰器1:', targetPrototype, methodName, paramIndex);
}
function paramDecorator2(params: string) {
console.log('方法参数装饰器2 before:', params);
return function (targetPrototype: any, methodName: string, paramIndex: number) {
console.log('方法参数装饰器2:', targetPrototype, methodName, paramIndex);
};
}
function paramDecorator3(params: string) {
console.log('方法参数装饰器3 before:', params);
return function (targetPrototype: any, methodName: string, paramIndex: number) {
console.log('方法参数装饰器3:', targetPrototype, methodName, paramIndex);
};
}
/**
* 静态属性修饰器
* @param targetPrototype
* @param propName
*/
function staticPropDecorator(param: string) {
console.log('静态属性修饰器 before:', param);
return function (targetPrototype: any, propName: string) {
console.log('静态属性修饰器:', targetPrototype, propName, targetPrototype[propName]);
targetPrototype[propName]="静态属性初始值被修改了!";
}
}
/**
* 静态方法修饰器
* @param targetPrototype
* @param methodName
* @param descriptor
*/
function staticMethodDecorator(param: string) {
console.log('静态方法修饰器 before:', param);
return function (targetPrototype: any, methodName: string, descriptor: PropertyDescriptor) {
console.log('静态方法修饰器:', targetPrototype, methodName, descriptor);
}
}
/**
* 类装饰器
* @param targetClass
*/
function classDecorator1(constructor: Function) {
console.log('类装饰器1:', constructor);
}
function classDecorator2(params: string) {
console.log('类装饰器2 before:', params);
return function (constructor: Function) {
console.log('类装饰器2:', constructor);
};
}
function classDecorator3(params: string) {
console.log('类装饰器3 before:', params);
return function (constructor: Function) {
console.log('类装饰器3:', constructor);
};
}
@classDecorator1
@classDecorator2('params2')
@classDecorator3('params3')
class Test {
@propDecorator1
@propDecorator2('param2')
@propDecorator3('param3')
public msg: string = "属性初始值";
@staticPropDecorator('静态属性')
static title: string = "静态属性初始值";
constructor(msg: string) {
this.msg = msg;
}
@methodDecorator1
@methodDecorator2('param2')
@methodDecorator3('param3')
toString(@paramDecorator1 str1: string, @paramDecorator2('param2') str2: string, @paramDecorator3('param3') str3: string) {
console.log('toString:', str1, str2, str3);
}
@staticMethodDecorator('静态方法')
static staticToString() {
console.log(this.title);
}
}
let t:any = new Test('this is a msg.');
t.toString("ss", "dd", "ff");//methodDecorator3装饰器对该方法进行了重写
console.log(t.msg, t.__proto__.msg);
Test.staticToString();
运行
//cmd
tsc test --target ES5 --experimentalDecorators
node test
结果
属性装饰器2 before: param2
属性装饰器3 before: param3
属性装饰器3: Test { toString: [Function] } msg
属性装饰器2: Test { toString: [Function] } msg undefined
属性装饰器1: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } msg
方法装饰器2 before: param2
方法装饰器3 before: param3
方法参数装饰器2 before: param2
方法参数装饰器3 before: param3
方法参数装饰器3: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString 2
方法参数装饰器2: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString 1
方法参数装饰器1: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString 0
方法装饰器3: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString { value: [Function],
writable: true,
enumerable: true,
configurable: true }
方法装饰器2: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString { value: [Function],
writable: true,
enumerable: true,
configurable: true }
方法装饰器1: Test { toString: [Function], msg: '会在原型上面添加该属性并赋值,不是实例对象' } toString { value: [Function],
writable: true,
enumerable: true,
configurable: true }
静态属性修饰器 before: 静态属性
静态属性修饰器: function Test(msg) {
this.msg = "属性初始值";
this.msg = msg;
} title 静态属性初始值
静态方法修饰器 before: 静态方法
静态方法修饰器: function Test(msg) {
this.msg = "属性初始值";
this.msg = msg;
} staticToString { value: [Function],
writable: true,
enumerable: true,
configurable: true }
类装饰器2 before: params2
类装饰器3 before: params3
类装饰器3: function Test(msg) {
this.msg = "属性初始值";
this.msg = msg;
}
类装饰器2: function Test(msg) {
this.msg = "属性初始值";
this.msg = msg;
}
类装饰器1: function Test(msg) {
this.msg = "属性初始值";
this.msg = msg;
}
toString: ss test dd test ff test
this is a msg. 会在原型上面添加该属性并赋值,不是实例对象
静态属性初始值被修改了!
欢迎讨论,觉得有用的点个赞呗 ~ +_+ ~