gpt4 book ai didi

javascript - 带有属性装饰器的 TypeScript 类就像静态的一样

转载 作者:行者123 更新时间:2023-11-30 08:32:40 26 4
gpt4 key购买 nike

我编写了一个带有属性装饰器的类,它在设置装饰属性时在类中设置一个标志。我还希望能够从该类的一个实例复制到另一个实例。问题是,当我在一个对象上设置属性值时,另一个对象上的属性值也会发生变化,就好像该属性是静态的一样。我是 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
});
}

关于javascript - 带有属性装饰器的 TypeScript 类就像静态的一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35493375/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com