> [!date] published: 2025-05-14 `private` accessor를 쓰면서 의문이 생긴 것들 정리하기 ## 1. private keyword는 JavaScript의 \#으로 컴파일되는가? > [!tip] 아니다! 참고 : [TypeScript: Documentation - Classes](https://www.typescriptlang.org/docs/handbook/2/classes.html#caveats) > Like other aspects of TypeScript’s type system, `private` and `protected` [are only enforced during type checking](https://www.typescriptlang.org/play?removeComments=true&target=99&ts=4.3.4#code/PTAEGMBsEMGddAEQPYHNQBMCmVoCcsEAHPASwDdoAXLUAM1K0gwQFdZSA7dAKWkoDK4MkSoByBAGJQJLAwAeAWABQIUH0HDSoiTLKUaoUggAW+DHorUsAOlABJcQlhUy4KpACeoLJzrI8cCwMGxU1ABVPIiwhESpMZEJQTmR4lxFQaQxWMm4IZABbIlIYKlJkTlDlXHgkNFAAbxVQTIAjfABrAEEC5FZOeIBeUAAGAG5mmSw8WAroSFIqb2GAIjMiIk8VieVJ8Ar01ncAgAoASkaAXxVr3dUwGoQAYWpMHBgCYn1rekZmNg4eUi0Vi2icoBWJCsNBWoA6WE8AHcAiEwmBgTEtDovtDaMZQLM6PEoQZbA5wSk0q5SO4vD4-AEghZoJwLGYEIRwNBoqAzFRwCZCFUIlFMXECdSiAhId8YZgclx0PsiiVqOVOAAaUAFLAsxWgKiC35MFigfC0FKgSAVVDTSyk+W5dB4fplHVVR6gF7xJrKFotEk-HXIRE9PoDUDDcaTAPTWaceaLZYQlmoPBbHYx-KcQ7HPDnK43FQqfY5+IMDDISPJLCIuqoc47UsuUCofAME3Vzi1r3URvF5QV5A2STtPDdXqunZDgDaYlHnTDrrEAF0dm28B3mDZg6HJwN1+2-hg57ulwNV2NQGoZbjYfNrYiENBwEFaojFiZQK08C-4fFKTVCozWfTgfFgLkeT5AUqiAA). > This means that JavaScript runtime constructs like `in` or simple property lookup can still access a `private` or `protected` member. > `private` also allows access using bracket notation during type checking. This makes `private`-declared fields potentially easier to access for things like unit tests, with the drawback that these fields are *soft private* and don’t strictly enforce privacy. 컴파일 결과에 `#` 가 붙지 않는다. ![[ba49e1d6-0c9a-435f-87c7-db6cb0cffaa7.png]] [TypeScript: TS Playground - An online editor for exploring TypeScript and JavaScript](https://www.typescriptlang.org/play?removeComments=true&target=99&ts=4.3.4#code/PTAEGMBsEMGddAEQPYHNQBMCmVoCcsEAHPASwDdoAXLUAM1K0gwQFdZSA7dAKWkoDK4MkSoByBAGJQJLAwAeAWABQIUH0HDSoiTLKUaoUggAW+DHorUsAOlABJcQlhUy4KpACeoLJzrI8cCwMGxU1ABVPIiwhESpMZEJQTmR4lxFQaQxWMm4IZABbIlIYKlJkTlDlXHgkNFAAbxVQTIAjfABrAEEC5FZOeIBeUAAGAG5mmSw8WAroSFIqb2GAIjMiIk8VieVJ8Ar01ncAgAoASkaAXxVr3dUwGoQAYWpMHBgCYn1rekZmNg4eUi0Vi2icoBWJCsNBWoA6WE8AHcAiEwmBgTEtDovtDaMZQLM6PEoQZbA5wSk0q5SO4vD4-AEghZoJwLGYEIRwNBoqAzFRwCZCFUIlFMXECdSiAhId8YZgclx0PsiiVqOVOAAaUAFLAsxWgKiC35MFigfC0FKgSAVVDTSyk+W5dB4fplHVVR6gF7xJrKFotEk-HXIRE9PoDUDDcaTAPTWaceaLZYQlmoPBbHYx-KcQ7HPDnK43FQqfY5+IMDDISPJLCIuqoc47UsuUCofAME3Vzi1r3URvF5QV5A2STtPDdXqunZDgDaYlHnTDrrEAF0dm28B3mDZg6HJwN1+2-hg57ulwNV2NQGoZbjYfNrYiENBwEFaojFiZQK08C-4fFKTVCozWfTgfFgLkeT5AUqiAA) ## 2. 그럼 private keyword와 \#중 어떤 것을 쓰는게 좋은가? > [!tip] 정답은 없고 상황에 따라 다르다. **런타임에서 접근을 제한해야 한다면 private fields(`#`)를 사용해야 한다.** **하지만 기존의 private keyword를 모두 private fields로 바꿀 필요는 없다.** private keyword는 많은 타입스크립트 개발자들이 오래 써왔고, 우리가 원하는 바(코드를 작성할 때 private property를 숨기는 것)를 잘 달성할 수 있게 해준다. ([class - What are the differences between the private keyword and private fields in TypeScript? - Stack Overflow](https://stackoverflow.com/questions/59641564/what-are-the-differences-between-the-private-keyword-and-private-fields-in-types)) Runtime에 Privacy Check를 추가하는 것은 성능에 영향을 줄 수도 있다. ([TypeScript: Documentation - Classes](https://www.typescriptlang.org/docs/handbook/2/classes.html#caveats)) ## 3. Code Style Guide > [!example] Style Guide > > 1. prefix, postfix로 underscore를 사용하는 것을 지양하자. - [Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html#naming-style) > 2. getter/setter는 지양하자 - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript?tab=readme-ov-file#accessors) [Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html#naming-style) > Do not use trailing or leading underscores for private properties or methods. 근데 이렇게 하면 getter 함수의 이름 짓기가 애매해진다. getter 함수의 이름이 프로퍼티 이름이랑 같으면 좋은데, 그럼 프로퍼티랑 getter 함수 이름이 겹치니까...? google style guide에서는 internal, value 같은 의미 있는 값들을 내부 프로퍼티의 이름에 사용하기를 권장한다. > If an accessor is used to hide a class property, the hidden property *may* be prefixed or suffixed with any whole word, like `internal` or `wrapped`. ```ts class Foo { private wrappedBar = ""; get bar() { return this.wrappedBar || "bar"; } set bar(wrapped: string) { this.wrappedBar = wrapped.trim(); } } ``` ~~(👆 그렇게 마음에 와닿는 방식은 아니다...)~~ [GitHub - airbnb/javascript: JavaScript Style Guide](https://github.com/airbnb/javascript?tab=readme-ov-file#accessors) > Do not use JavaScript getters/setters as they cause unexpected side effects and are harder to test, maintain, and reason about. Airbnb JavaScript Style Guide 에서는 getter/setter 사용을 지양하자고 말하고 있다. 생각해보니 외부에서 사용할 때 `foo.bar` 요렇게 쓰면 이 `bar`가 public인지 private인데 getter로 접근하는 것인지 명시적으로 드러나지를 않는다는 단점이 있는 것 같기도 하다.. ㅇㅇ