首页 文章

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

提问于
浏览
2

在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 )?

3 回答

  • 1

    您也可以在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");
                }
            });
        }
    }
    

    Note 你不能使用在类本身上定义的值,否则在你遇到 Maximum call stack size exceeded 之前会递归调用该字段的getter . 类定义上的 value:any 声明避免了编译器错误:

    属性“value”不存在于Field类型的值上

    然后,您可以执行此TypeScript代码以获得与JavaScript代码示例相同的结果:

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

    在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 .

  • 4

    如果您不创建变量,则无法访问它:

    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;
        }
    }
    

相关问题