如何防止get/set函数暴露Typescript中本地属性

vptzau2j  于 2023-05-08  发布在  TypeScript
关注(0)|答案(4)|浏览(197)

在Javascript中,我可以用get/set方法创建对象的属性:

function Field(arg){
    var value = arg;

    // Create a read only property "name"
    Object.defineProperty(this, "value", {           
        get: function () {
            return value;
        },
        set: function () {
            console.log("cannot set");
        }
    });
}

var obj = new Field(10);    
console.log(obj.value); // 10
obj.value = 20;         // "cannot set"

此处不允许设置value属性。
在TypeScript中,如果我想实现同样的行为,我必须这样做(正如get and set in TypeScript所建议的那样):

class Field {
    _value: number;

    constructor(arg) {
        this._value = arg;
    }

    get value() {
        return this._value;
    }

    set value() {
        console.log("cannot set");
    }
}

var obj = new Field(10);

console.log(obj.value); // 10
obj.value = 20;         // "cannot set"
obj._value = 20;        // ABLE TO CHANGE THE VALUE !
console.log(obj.value); // 20

但是这里的问题是,所谓的私有属性_value可以由用户直接访问/更改,而不需要通过value的get/set方法。如何限制用户直接访问此属性(_value)?

ccrfmcuu

ccrfmcuu1#

你也可以在TypeScript中使用Object.defineProperty
我修改了你的Field类,如下所示:

class Field{
    value: any;
    constructor(arg: any)
    {
        var value = arg;
        Object.defineProperty(this, "value",{           
            get: () => {
                return value;
            },
            set: function () {
                console.log("cannot set");
            }
        });
    }
}

注意不能使用类本身定义的值,否则会递归调用字段的getter,直到遇到Maximum call stack size exceeded。类定义上的value:any声明避免了编译器错误:

字段类型值不存在属性“value
然后,您可以执行此TypeScript代码以获得与JavaScript代码示例相同的结果:

var obj = new Field(10);
console.log(obj.value);
obj.value = 20;
m4pnthwp

m4pnthwp2#

在TypeScript中,它应该像添加private修饰符一样简单(在您的示例中,_value是公共的):

private _value:number;

...编译器现在应该阻止您从类外部设置属性:

var obj = new Field(10);
obj._value = 20; // Error: The property '_value' does not exist on value of type 'Field'.

但是这并没有在输出JS中以同样的方式隐藏_value。TypeScript私有成员仅在TS中是私有的。请参阅this answer和它链接到的有趣的codeplex discussion

cfh9epnr

cfh9epnr3#

使用readonly修饰符初始化它。

class Field {
    readonly _value: number;

    constructor(arg) {
        this._value = arg;
    }
}

这是一个更清晰的实现。

l7mqbcuq

l7mqbcuq4#

如果你不创建一个变量,它将不可访问:

class Field{
    get value(){
        return 10;
    }

    set value(){
        console.log("cannot set");
    }
}

var obj = new Field();
console.log(obj.value); // 10
obj.value = 20;  // cannot set
console.log(obj.value); // 10

当然,我会建议删除所有设置在一起:

class Field{
    get value(){
        return 10;
    }
}

相关问题