타입스크립트에서 접근 수정자는 클래스의 속성과 메소드의 가시성을 제한하는 데 사용됩니다:
class Animal { public name: string; private age: number; protected kind: string; constructor(name: string, age: number, kind: string) { this.name = name; this.age = age; this.kind = kind; } } class Dog extends Animal { bark() { console.log(this.kind); // OK: protected // console.log(this.age); // 오류: 상속 클래스에서 private는 보이지 않음 } } const dog = new Dog('샤릭', 5, '포유류'); console.log(dog.name); // OK // console.log(dog.kind); // 오류: protected // console.log(dog.age); // 오류: private
#field, 하지만 이것은 JS의 사양이며 다르게 컴파일됩니다.질문: 타입스크립트 클래스의 private 속성에 JavaScript로 컴파일한 후 접근할 수 있습니까?
답변: 예, private(및 protected)는 타입스크립트의 컴파일 단계에서의 검사이기 때문에, ES5 또는 ES6로 컴파일된 후에는 프라이버시가 유지되지 않고, 속성은 객체에 남아 있으며 속성 이름을 통해 접근할 수 있습니다(예: object['privateProp'] 사용).
// 컴파일된 JS 코드 function Animal(name, age, kind) { this.name = name; this.age = age; this.kind = kind; } var dog = new Animal('샤릭', 5, '포유류'); console.log(dog['age']); // 5 — TS 수준에서만 접근 불가!
이야기
대형 프로젝트에서 개발자는 런타임에서 private 필드의 접근 불가능성을 신뢰했습니다. 결과적으로 객체를 직렬화(JSON.stringify)하여 전송할 때 우연히 기밀 데이터가 로그에 포함되었습니다. TS의 타입 검사가 실제 접근으로부터 보호하지 못한 것입니다.
이야기
프로젝트에서는 동적으로 속성을 추가하여 클래스 인스턴스를 "확장"하는 메커니즘이 구현되었습니다. 동적으로 추가된 속성이 private 이름을 덮어쓰게 되었고 외부 코드에 의해 우연히 수정되었습니다. 이 오류는 production에서만 발견되었으며, 프라이버시가 보장되지 않았습니다.
이야기
JavaScript에서 타입스크립트로 마이그레이션하는 과정에서 팀은 protected를 사용하기 시작했으며, 이는 자식 클래스 외부에서 필드 사용을 방지한다고 믿었습니다. 그러나 프로그래머가
Object.assign을 통해 보호된 필드를 런타임에서 실수로 덮어쓰게 되어 추적하기 어려운 버그가 발생했습니다. 이는 런타임 캡슐화가 없기 때문에 가능했습니다.