2016-07-26 3 views
0

У меня есть класс, который содержит частное свойство, которое является массивом. Существует публичный геттер и сеттер, чтобы гарантировать, что манипулирование данными вызывает требуемую бизнес-логику.Вызов открытого скрипта скриптов изменяет частную собственность без запуска логики, содержащейся в общедоступном сетевом уровне

У меня возникла проблема, когда вызывающий пользователь смог установить частную собственность, не запуская связанную логику, содержащуюся в публичном сетевом устройстве.

я воспроизвел этот вопрос с помощью этого простого кода:

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

Мой вопрос: Могу ли я делать что-то неправильно? Это предполагаемое поведение? Или это больше проблема с машинописным компилятором, который не должен позволять компиляции этого кода?

+0

Какая часть в этом случае неожиданна? –

+0

Я бы ожидал, что в обоих случаях значение будет: setter_test – user1769949

ответ

1

Рассматривая конкретно эти две строки:

greeter.greetings = ["test"]; 

и

greeter.greetings[0] = "test" 

Они похожи, но они на самом деле совсем другое. Эта строка здесь говорит : greetings Недвижимость 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"; 

Как вы можете видеть, мы не установитьgreetings в собственность, мы получить это! Затем мы устанавливаем свойство массива. Установщик greetings не используется.

Начиная с TypeScript 2.0 (в бета-версии на момент написания) вы сможете использовать ReadonlyArray<string> для представления массивов, которые можно читать, но не писать. Это позволит вам разоблачить пользователей ReadonlyArray<string>, но у них есть string[] как поле private.

+0

Это имеет смысл - спасибо за то, что нашли время, чтобы объяснить это новичкам машинописного текста. – user1769949

 Смежные вопросы

  • Нет связанных вопросов^_^