在我的库中(对于AngularJS)我正在尝试实现以下功能:
Object.defineProperty
定义的getter。但我在巴贝尔遇到了意想不到的行为。在库中使用的Typescript中,它运行良好,但是Babel创建了一些代码,这些代码将已经定义的属性重新定义为它的初始化器。
这是ES2015中的装饰类:
@Component({
selector: 'test'
})
export class TestClass {
@Inject('$http') $http;
@Inject('$q') $q;
}
结果代码:
var TestClass = exports.TestClass = (_dec9 = (0, _ngMetasys.Component)({
selector: 'test'
}), _dec10 = (0, _ngMetasys.Inject)('$http'), _dec11 = (0, _ngMetasys.Inject)('$q'), _dec9(_class4 = (_class5 = function TestClass() {
(0, _classCallCheck3.default)(this, TestClass);
// everything is OK, TestClass.prototype.$http is a getter with function () => $http.
_initDefineProp(this, '$http', _descriptor5, this); // there are dragons. Property $http is redefined to undefined.
_initDefineProp(this, '$q', _descriptor6, this);
}, (_descriptor5 = _applyDecoratedDescriptor(_class5.prototype, '$http', [_dec10], {
enumerable: true,
initializer: null
}), _descriptor6 = _applyDecoratedDescriptor(_class5.prototype, '$q', [_dec11], {
enumerable: true,
initializer: null
})), _class5)) || _class4);
如何禁用此属性重新定义?有没有办法避免巴贝尔的财产重新定义或替代它?
答案 0 :(得分:0)
我想我找到了问题的答案。 babel-plugin-transform-decorators-legacy
中有一个测试允许设置属性描述符,甚至可以将简单属性转换为getter。
有一个限制。如果你想记住装饰者稍后改变它,它将无法工作。我没有正确调查它,但我认为我的问题是我在类(和属性)初始化后更改描述符的事实,并且我对描述符所做的更改不会影响已初始化的属性。
所以有测试给了我提示。它来自here。
it('should support mutating an initialzer into an accessor', function(){
function dec(target, name, descriptor){
expect(target).to.be.ok;
expect(name).to.eql("prop");
expect(descriptor).to.be.an('object');
let {initializer} = descriptor;
delete descriptor.initializer;
delete descriptor.writable;
let value;
descriptor.get = function(){
if (initializer){
value = '__' + initializer.call(this) + '__';
initializer = null;
}
return value;
};
}
class Example {
@dec
prop = 3;
}
let inst = new Example();
expect(inst.prop).to.eql('__3__');
});