javascript中decorator

js装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
配置在typescript中使用装饰器
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */

/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"noEmitOnError": true,
}

然后直接 tsc -p . 后产生对应的js文件后,node xx.js即可。
当然也可以用babel将ts转js。


1. typesript自带的tsc编译器。可以将ts转为es5,
2. es6语法的js文件要借助babel和插件,将es6转为es5.
但是这两种最后产生的es5的js文件并不是一样的。因为编译器都是自己的转换规则。
最后才可以在浏览器中运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
下面我都包装了一下,可以传参数在装饰器。
1. 类装饰器,只传入了一个target,即所修饰的构造函数。如[Function: Home]
export function Log() {
return function(target) {
console.log('这是类注解');
target.prototype.xixi = function() {
console.log(`xixi in prototype...`);
}
}
}

2. 属性装饰器,参数有2个(target, propertyKey)
export function Property(name:string) {
console.log(name + "Property注解参数")
return function(target: Object, propertyKey: string) {
console.log(`${target} 属性名为 ${propertyKey} 属性值为`);
}
}

3. 方法装饰器,参数有三个(target, name, descriptor),相当于Object.defineProperty(obj,prop,descriptor)
export function LogTest(name: string) {
return function(target, name, descriptor) {
console.log(`这是LogTest注解`)
let oldMethod = descriptor.value;
// 这里vlaue就是注解下的方法体,然后给会将参数传递过来。
descriptor.value = (thing, time) => {
console.log(`Calling ${name} with ${thing} + ${time}`);
// Home { say: [Function], doSomething: [Function], xixi: [Function] }
console.log(target);
oldMethod.call(target, thing, time);
};
return descriptor;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { Log, Decorator,LogTest, Property } from './Log';

@Log()
export class Home {

@Property("这是姓名")
name: string = 'daejong';

@Property("这是年龄")
age: string = '24';

@Decorator({"name": "dottie", "age":'23'})
say(name: string) {
console.log(`say hi in mine...`)
}


@LogTest("Hello")
doSomething(thing: string, time: string) {
console.log(`do ${thing} and ${time} ...`);
}

}

// let home = new Home();
// home.xixi();
// home.say('dottie参数');
// home.say = function() {
// console.log(`修改失败。。。`)
// }
// home.doSomething('大扫除', '1小时');
// console.log(home.name);

/*
这是姓名Property注解
[object Object] 属性名为 name 属性值为 undefined
这是年龄Property注解
[object Object] 属性名为 age 属性值为 undefined
name = dottie
age = 23
这是Decorator方法注解
修改方法为只读。。方法参数为[object Arguments]
这是LogTest注解
这是类注解
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
export function Log() {
return function(target) {
console.log('这是类注解');
target.prototype.xixi = function() {
console.log(`xixi in prototype...`);
}
}
}

export function Decorator(value: {[key: string]: string}) {
Object.keys(value).forEach(key => console.log(`${key} = ${value[key]}`));
return function(target, name, descriptor) {
console.log('这是Decorator方法注解');
let args = Array.prototype.slice.call(arguments);
console.log(`修改方法为只读。。方法参数为${arguments}`)
descriptor.writable = false;
args.forEach(arg => {
// console.log(arg)
/*
Home { say: [Function] }
say
{ value: [Function],
writable: false,
enumerable: true,
configurable: true }
*/
});
return descriptor;
}
}

export function LogTest(name: string) {
return function(target, name, descriptor) {
console.log(`这是LogTest注解`)
let oldMethod = descriptor.value;
// 这里vlaue就是注解下的方法体,然后给会将参数传递过来。
descriptor.value = (thing, time) => {
console.log(`Calling ${name} with ${thing} + ${time}`);
// Home { say: [Function], doSomething: [Function], xixi: [Function] }
console.log(target);
oldMethod.call(target, thing, time);
};
return descriptor;
}
}

export function Property(name:string) {
console.log(name + "Property注解")
return function(target, propertyKey: string) {
console.log(`${target} 属性名为 ${propertyKey} 属性值为`);
}
}