Open zyhcool opened 4 years ago
@zyhcool 可以对比一下加了 @Injectable() 与不加时,TestService 编译后的代码是什么
@jkchao 谢谢回复!
我修改了一下代码
// ts源码
import "reflect-metadata";
const Injectable = (): ClassDecorator => target => {};
@Injectable()
class C {
constructor(s:string){
}
}
function Factory(constructor){
console.log(Reflect.getMetadata("design:paramtypes",constructor));
}
Factory(C);
这是加入@Injectable()
后编译的js代码:
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length,
r = c < 3
? target
: desc === null
? desc = Object.getOwnPropertyDescriptor(target, key)
: desc,
d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
r = Reflect.decorate(decorators, target, key, desc);
} else {
for (var i = decorators.length - 1; i >= 0; i--) {
if (d = decorators[i]) {
r = (
c < 3
? d(r)
: c > 3
? d(target, key, r)
: d(target, key)
) || r;
}
}
}
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
exports.__esModule = true;
require("reflect-metadata");
var Injectable = function () { return function (target) { }; };
var C = /** @class */ (function () {
function C(s) {
}
C = __decorate([
Injectable()
], C);
return C;
}());
function Factory(constructor) {
console.log(Reflect.getMetadata("design:paramtypes", constructor));
}
Factory(C);
这是去掉@Injectable()
后编译的js代码:
"use strict";
exports.__esModule = true;
require("reflect-metadata");
var Injectable = function () { return function (target) { }; };
var C = /** @class */ (function () {
function C(s) {
}
return C;
}());
function Factory(constructor) {
console.log(Reflect.getMetadata("design:paramtypes", constructor));
}
Factory(C);
本质上加了@Injectable()
后,只是多了一个__decorate
函数和其中的Reflect.decorate
方法,这个是reflect-metadata
写的的polyfill,有什么影响吗?
而且运行编译后的js文件(加了@Injectable()
的),打印结果却是undefined
,为什么?
难道Reflect.metadata
只能在TS中使用,而且一定要在作为装饰器的函数中?
@zyhcool 使用 Reflect Metadata 需要打开 emitDecoratorMetadata 编译选项,然后再对比一下编译后的结果,其中使用 @ Injectable
的,有一句很关键的代码 __metadata("design:paramtypes", [String])
,把 [String]
存储到了 key 为 design:paramtypes 的元信息里面。
@jkchao 谢谢大佬,已经解决我的疑惑了!
我之前使用tsc
编译确实没有带上--experimentalDecorators
和--emitDecoratorMetadata
选项,加上后得到的编译结果多了个__metadata
函数
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
牛!
有个疑问请教各位: 在这篇文章此处有段代码:
其中 Injectable 装饰器实质上并没有对 TestService 类进行修改,那为什么这边还要加上这个类装饰器呢? 实验证明,如果不加上的话,
Reflect.getMetadata('design:paramtypes', target)
将无效,这是为什么呢?谢谢解答!