调用Typescript public setter修改私有属性,而不运行public setter中包含的逻辑

时间:2016-07-26 20:43:42

标签: typescript typescript1.8

我有一个包含私有属性的类,这是一个数组。有一个公共getter和setter来确保数据操作触发所需的业务逻辑。

当调用者能够设置私有属性而不运行公共setter中包含的关联逻辑时,我遇到了一个问题。

我用这个简单的代码重现了这个问题:

class Greeter {
    private _greetings: string[];
    constructor () {}
    set greetings(greetings: string[]) {
        let newGreetings: string[] = [];
        for (let i: number = 0; i < greetings.length; i++) {
            newGreetings.push("setter_" + greetings[i] )
        }
        this._greetings = newGreetings;
    }

    get greetings() {
        return this._greetings;
    }
}

let greeter = new Greeter();
greeter.greetings = ["test"];
let test1 = document.createElement('p');
test1.textContent = greeter.greetings[0];
document.body.appendChild(test1);

greeter.greetings[0] = "test";
let test2 = document.createElement('p');
test2.textContent = greeter.greetings[0];
document.body.appendChild(test2);

要查看TS游乐场中的代码,请按以下链接:

https://www.typescriptlang.org/play/#src=class%20Greeter%20%7B%0D%0A%20%20%20%20private%20_greetings%3A%20string%5B%5D%3B%0D%0A%20%20%20%20constructor%20()%20%7B%7D%0D%0A%20%20%20%20set%20greetings(greetings%3A%20string%5B%5D)%20%7B%0D%0A%09%09let%20newGreetings%3A%20string%5B%5D%20%3D%20%5B%5D%3B%0D%0A%09%09for%20(let%20i%3A%20number%20%3D%200%3B%20i%20%3C%20greetings.length%3B%20i%2B%2B)%20%7B%0D%0A%09%09%09newGreetings.push(%22setter_%22%20%2B%20greetings%5Bi%5D%20)%0D%0A%09%09%7D%0D%0A%09%09this._greetings%20%3D%20newGreetings%3B%0D%0A%09%7D%0D%0A%09%0D%0A%09get%20greetings()%20%7B%0D%0A%09%09return%20this._greetings%3B%0D%0A%09%7D%0D%0A%0D%0A%7D%0D%0A%0D%0Alet%20greeter%20%3D%20new%20Greeter()%3B%0D%0Agreeter.greetings%20%3D%20%5B%22test%22%5D%3B%0D%0Alet%20test1%20%3D%20document.createElement('p')%3B%0D%0Atest1.textContent%20%3D%20greeter.greetings%5B0%5D%3B%0D%0Adocument.body.appendChild(test1)%3B%0D%0A%0D%0Agreeter.greetings%5B0%5D%20%3D%20%22test%22%3B%0D%0Alet%20test2%20%3D%20document.createElement('p')%3B%0D%0Atest2.textContent%20%3D%20greeter.greetings%5B0%5D%3B%0D%0Adocument.body.appendChild(test2)%3B%0D%0A

我的问题是:我做错了吗?这是预期的行为吗?或者这更像是一个打字稿编译器的问题,它不应该允许这个代码编译?

1 个答案:

答案 0 :(得分:1)

具体看这两行:

greeter.greetings = ["test"];

greeter.greetings[0] = "test"

它们看起来很相似,但它们确实非常不同。这一行说明greetings的{​​{1}}属性设置为greeter 。我们会调用["test"] setter,因为我们正在设置greetings属性。

greetings

相反,这条线应该被认为是两个操作

greeter.greetings = ["test"];

正如您所看到的,我们不会设置 // this line... greeter.greetings[0] = "test" // ...is the same as const tmp = greeter.greetings; tmp[0] = "test"; 属性,我们获取它!然后我们设置数组的属性。 <{1}} setter未使用。

从TypeScript 2.0开始(在撰写本文时为测试版),您将能够使用greetings来表示可以读取但不能写入的数组。这样,您就可以向消费者展示greetings,但会定期ReadonlyArray<string>作为ReadonlyArray<string>字段。