2016-07-26 2 views
0

Ich habe eine Klasse, die eine private Eigenschaft enthält, die ein Array ist. Es gibt einen öffentlichen Getter und Setter, um sicherzustellen, dass die Datenmanipulation die erforderliche Geschäftslogik auslöst.Das Aufrufen des öffentlichen Typs "Typoskript" ändert die private Eigenschaft, ohne die im Öffentlichen Setter enthaltene Logik auszuführen

Ich stieß auf ein Problem, wenn ein Aufrufer in der Lage war, die private Eigenschaft festzulegen, ohne die zugehörige Logik auszuführen, die im öffentlichen Setter enthalten ist.

ich das Problem mit diesem einfachen Code reproduziert:

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

Um den Code in TS Spielplatz, folgen Sie dem Link unten zu sehen:

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

Meine Frage ist: Bin ich etwas zu tun falsch? Ist das das beabsichtigte Verhalten? Oder ist das eher ein Problem mit dem Typskript-Compiler, der diesen Code nicht kompilieren sollte?

+0

Welcher Teil ist speziell unerwartet? –

+0

Ich würde erwarten, dass in beiden Fällen der Wert sein wird: setter_test – user1769949

Antwort

1

Betrachtet man speziell diese beiden Zeilen:

greeter.greetings = ["test"]; 

und

greeter.greetings[0] = "test" 

sie ähnlich aussehen, aber sie sind wirklich ganz anders aus. Diese Linie hier sagt setzt die greetings Eigenschaft von greeter zu ["test"]. Der greetings Setter wird aufgerufen, weil wir die greetings-Eigenschaft festlegen.

greeter.greetings = ["test"]; 

Im Gegensatz dazu diese Linie wirklich von

// this line... 
greeter.greetings[0] = "test" 
// ...is the same as 
const tmp = greeter.greetings; 
tmp[0] = "test"; 

als zwei Operationen gedacht werden sollte Wie Sie sehen können, haben wir nicht gesetzt die greetings Eigenschaft, wir es bekommen ! Dann setzen wir eine Eigenschaft des Arrays. Der greetings Setter wird nicht verwendet.

Beginnend in TypeScript 2.0 (in der Beta zum Zeitpunkt des Schreibens) können Sie ReadonlyArray<string> verwenden, um Arrays darzustellen, die zwar gelesen, aber nicht beschrieben werden können. Auf diese Weise können Sie den Benutzern eine ReadonlyArray<string> zur Verfügung stellen, haben aber ein reguläres string[] als private Feld.

+0

Das macht Sinn - danke, dass Sie sich Zeit genommen haben, dies einem Typoskript-Neuling zu erklären. – user1769949

Verwandte Themen