带有属性装饰器的 TypeScript 类就像静态一样
TypeScript class with property decorator acts as if static
我写了一个带有属性装饰器的类,当设置装饰属性时,该类会在类中设置一个标志。我还希望能够从类的一个实例复制到另一个实例。问题是,当我在一个对象上设置属性的值时,另一个对象上的属性值也会更改,就好像属性是静态的一样。我是JavaScript和TypeScript的新手。我错过了什么?
运行下面的文本代码将记录:
Setting propNum from undefined to 0
testclass.ts:18 Setting propNum from 0 to 123
test.spec.ts:13 t1.propNum = 123
test.spec.ts:14 t2.propNum = 123
t1.propNum 仍应为零
装饰
//
// property decorator to set dirty flag automatically for any decorated property
//
function testProperty( target: any, key: string ) {
// property value
var _val = this[key];
// property getter
function getter() {
return _val;
};
// property setter
function setter( newVal ) {
if ( _val != newVal ) {
console.log( `Setting ${key} from ${_val} to ${newVal}` );
_val = newVal;
this._dirty = true;
}
};
//
// Delete original property and define new property with getter & setter
//
if ( delete this[key] ) {
// Create new property with getter and setter
Object.defineProperty( target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
}
测试类
export class TestClass {
private _dirty: boolean;
@testProperty
public propNum: number = 0;
constructor() {
this._dirty = false;
}
public copyFrom( tc: TestClass ) {
this.propNum = tc.propNum;
}
}
测试代码
describe( 'Copy Class Test', () => {
it( 'Copy Test', () => {
var t1 = new TestClass();
var t2 = new TestClass();
t2.propNum = 123;
console.log( `t1.propNum = ${t1.propNum}` );
console.log( `t2.propNum = ${t2.propNum}` );
expect( t1.propNum ).toBe( 0 );
t1.copyFrom( t2 );
expect( t1.propNum ).toBe( 123 );
});
});
这里的主要问题是 getter 和 setter 共享同一个变量,而不是基于实例获取值。
这基本上与这样做相同:
function TestClass() {
}
var value;
Object.defineProperty(TestClass.prototype, "propNum", {
get: function() { return value; },
set: function(val) { value = val },
enumerable: true,
configurable: true
});
这会导致这种情况发生:
var a = new TestClass(), b = new TestClass();
a.propNum = 2;
a.propNum === b.propNum; // true, because they're both referencing the same variable
第二个问题是this[key]
引用全局对象的属性。
您可能想要做的是以下几行(未经测试的代码):
function testProperty( target: Object, key: string ) {
const privateKey = "_" + key;
function getter() {
return this[privateKey];
}
function setter( newVal: any ) {
if ( this[privateKey] != newVal ) {
console.log( `Setting ${key} from ${this[privateKey]} to ${newVal}` );
this[privateKey] = newVal;
this._dirty = true;
}
}
Object.defineProperty( target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
相关文章:
- 如何处理10页以上的静态页眉/页脚
- Grunt-connect在根目录之外提供静态文件
- 使用向下箭头键(与tab键一样)聚焦下一个输入
- 来自文档或下一个静态父级的事件委派
- JavaScript命名约定;静态“;类或模块
- 无法理解JavaScript中的静态方法
- 使用主干网和rails的静态页面路由
- Javascript,从静态函数中打印全局对象
- 在SVG地图上添加水的渐变,就像在谷歌地图(PHP/JS)中一样
- 如何像模糊图像一样模糊iframe
- FullCalendar:事件发生时阻止重叠.标题是一样的
- 如何检测滚动事件是否像在触摸设备上一样只触发一次
- 带静态字符e输入的文本框数字和带javascript的负整数
- DIV怎么能像Javascript中的另一个元素一样工作呢
- 我正在创建一个聊天,但每次我发送消息时,它都不会让我再发送另一条消息,就像表格一样;不起作用
- 在Hapi.js中提供静态JavaScript文件不起作用
- 压缩静态HTML文件中的JS和CSS
- 带有属性装饰器的 TypeScript 类就像静态一样
- 在 Angular JS 中可能像静态一样的数组
- 如何在 GWT 中注入静态 CSS 文件,就像使用 JS 文件一样