问题描述
我发现了一些使用装饰器作为类中实例变量的代码...
我试图用普通的 Javascript 复制它,但它不起作用。
这是打字稿:
export function Observableproperty() {
return (obj: Observable,key: string) => {
let storedValue = obj[key];
Object.defineProperty(obj,key,{
get: function () {
return storedValue;
},set: function (value) {
if (storedValue === value) {
return;
}
storedValue = value;
this.notify({
eventName: Observable.propertyChangeEvent,propertyName: key,object: this,value
});
},enumerable: true,configurable: true
});
};
}
然后,在课堂上:
export class MyClass extends Observable {
@Observableproperty() public theBoolValue: boolean;
…
我尝试了各种方法来实例化我的 JS 变量 - 总是出错......
喜欢:
@ObservableProperty
this.theBoolValue = false;
这甚至可能吗?
解决方法
装饰器是 TypeScript 的东西,而不是 JavaScript 的东西 (yet)
看看 TypeScript Docs,你可以拿他们的例子(甚至你的例子),然后把它扔到他们的 Playground 中以获得等效的 JavaScript。
For example,这是 TypeScript 示例:
function first() {
console.log("first(): factory evaluated");
return function (target: any,propertyKey: string,descriptor: PropertyDescriptor) {
console.log("first(): called");
};
}
function second() {
console.log("second(): factory evaluated");
return function (target: any,descriptor: PropertyDescriptor) {
console.log("second(): called");
};
}
class ExampleClass {
@first()
@second()
method() {}
}
这在 JavaScript 中归结为:
"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,desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target,r) : d(target,key)) || r;
return c > 3 && r && Object.defineProperty(target,r),r;
};
var __metadata = (this && this.__metadata) || function (k,v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k,v);
};
function first() {
console.log("first(): factory evaluated");
return function (target,propertyKey,descriptor) {
console.log("first(): called");
};
}
function second() {
console.log("second(): factory evaluated");
return function (target,descriptor) {
console.log("second(): called");
};
}
class ExampleClass {
method() { }
}
__decorate([
first(),second(),__metadata("design:type",Function),__metadata("design:paramtypes",[]),__metadata("design:returntype",void 0)
],ExampleClass.prototype,"method",null);
,
装饰器仍然是一个提案,尚未正式添加到 JS 中。它们目前正在进行重大的重新设计,它们将与当前的 TypeScript 实现大不相同,后者基于提案的第一个版本。您可以在此处了解提案的进展情况: https://github.com/tc39/proposal-decorators
您也可以同时使用 Babel 在 JS 中尝试装饰器,但这也是基于旧的提案(即使关闭了 legacy
选项...因为装饰器实际上现在是第三个版本)。
https://babeljs.io/docs/en/babel-plugin-proposal-decorators
因此请记住,这只是一种权宜之计,将来代码可能永远不会在浏览器中以本机方式运行 - 无论何时完成,您都需要重构它以匹配新的装饰器提案。>