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

时间:2013-03-20 03:29:32

标签: typescript

在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 个答案:

答案 0 :(得分:4)

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

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

  

属性“value”在类型Field

的值上不存在

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

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

答案 1 :(得分:1)

在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

答案 2 :(得分:0)

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

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