Test links in markdown.

This commit is contained in:
gnu4cn 2019-03-27 16:51:18 +08:00
parent 615a7a32f2
commit 618df2aab9
7 changed files with 155 additions and 835 deletions

View File

@ -29,7 +29,7 @@ tsc --target ES5 --experimentalDecorators
## 关于装饰器Decorators
*装饰器* 是一类特殊的声明,可被附加到[类的声明](#class-decorators)、[方法](#method-decorators)、[访问器](#accessor-decorators)、[属性](#property-decorators)或者[参数](#parameter-decorators)。装饰器使用的形式是`@expression`,其中的`expression`必须评估为一个将在运行时,以有关被装饰声明的信息被调用的函数Decorators use the form `@expression`, where `expression` must evaluate to a function that will be called at runtime with information about the decorated declaration
*装饰器* 是一类特殊的声明,可被附加到[类的声明](#class-decorators)、[方法](#method-decorators)、[访问器](#accessor-decorators)、[属性](#property-decorators)或者[参数](#parameter-decorators)。装饰器采用`@expression`形式,其中的`expression`求值后必须是一个函数,在运行时该函数将以被装饰的声明有关的信息,被调用到Decorators use the form `@expression`, where `expression` must evaluate to a function that will be called at runtime with information about the decorated declaration
比如,对于给定的装饰器`@sealed`,那么就可能向下面这样写该`sealed`函数:
@ -42,7 +42,6 @@ function sealed(target) {
> 注意:在下面的[类装饰器](#class-decorators)中,可以看到更详细的示例
### 装饰器工厂Decorator Factories
<a href="decorator-factories"></a>
可通过编写一个装饰器工厂,来对装饰器作用于声明的方式进行定制。 *装饰器工厂* 就是一个返回由装饰器在运行时调用的表达式的函数If you want to customize how a decorator is applied to a declaration, we can write a decorator factory. A *Decorator Factory* is simply a function that returns the expression that will be called by the decorator at runtime
@ -282,3 +281,66 @@ Class Point {
get y() { return this._y; }
}
```
使用以下的函数声明,可定义出该`@configurable`装饰器:
```typescript
function configurable (value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
}
}
```
### 属性装饰器Property Decorators
*属性装饰器* 是紧接着某个属性声明之前进行声明的。在声明文件中,以及任何其他外围上下文(比如在某个`declare`类中),都不能使用属性装饰器。
属性装饰器的表达式,将在运行时作为函数进行调用,有着以下两个参数:
1. 某个静态成员的类构造函数,或某个实例成员的类的原型;
2. 该成员的名称。
> **注意** 由于在TypeScript中属性装饰器初始化方式的原因将不会把 *属性描述符* 提供给属性装饰器。这是因为在定义某个原型的成员时,目前还没有对实例属性进行描述的机制,同时也没有对某个属性的初始化器进行观察与修改的途径。由于上述原因,属性装饰器的返回值也被加以忽略了。那么属性装饰器就只能用于已声明为某个类的、某个指定名称的属性进行观察了。
有了这些信息,就可以记录有关该属性的元数据了,如下面的示例:
```typescript
class Greeter {
@format("Hello, %s")
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet () {
let formatString = getFormat(this, "greeting");
return formatString.replace(""%s", this.greeting);
}
}
```
此时就可以使用下的函数声明,来定义该`@format`装饰器与`getFormat`函数:
```typescript
import "reflect-metadata";
// const formatMetadataKey = Symbol("format");
// const formatMetadataKey: Symbol;
//
// 上面两种写法都不行估计是新版本的typescript已经不支持 Symbol 类型变量的初始化了
let formatMetadataKey: Symbol;
function format (formatMetadataKey: string) {
return Reflect.metadata(formatMetadataKey, formatString);
}
function getFormat (target: any, propertyKey: string) {
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
```
这里的装饰器 `@format("Hello, %s")`是一个 [装饰器工厂](#装饰器工厂Decorator Factories)

View File

@ -20,7 +20,7 @@ gulp.task('tsc', () => {
// 这里 watch 里必须使用 gulp.series
gulp.task('watch', () => {
gulp.watch('src/*ts', gulp.series('tsc'));
gulp.watch('src/*.ts', gulp.series('tsc'));
});

877
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,11 +23,13 @@
},
"homepage": "https://github.com/gnu4cn/ts-learnings#readme",
"devDependencies": {
"@types/reflect-metadata": "^0.1.0",
"gulp": "^4.0.0",
"gulp-sourcemaps": "^2.6.1",
"gulp-typescript": "^3.2.3",
"gulp-typescript": "^5.0.1",
"gulp-uglify": "^3.0.0",
"live-server": "^1.2.0",
"typescript": "^2.6.2"
}
},
"dependencies": {}
}

View File

@ -1,3 +1,7 @@
'use strict';
import "reflect-metadata";
// 访问器装饰器Accessor Decorator
class Point {
private _x: number;
private _y: number;
@ -18,3 +22,31 @@ function configurable(value: boolean) {
descriptor.configurable = value;
};
}
// 属性装饰器property decorator
class Greeter {
@format("Hello, %s")
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet () {
let formatString = getFormat(this, "greeting");
return formatString.replace("%s", this.greeting);
}
}
let formatMetadataKey: Symbol;
function format (formatString: string) {
return Reflect.metadata(formatMetadataKey, formatString);
}
function getFormat (target: any, propertyKey: string) {
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
let g = new Greeter("彭海林");
console.log(g.greet());

2
src/symbol.ts Normal file
View File

@ -0,0 +1,2 @@
let a: Symbol;
console.log(a);

View File

@ -6,6 +6,9 @@
"noImplicitAny": true,
"target": "es5",
"outDir": "dist/",
"experimentalDecorators": true
"experimentalDecorators": true,
"types": [
"reflect-metadata"
]
}
}