본문으로 바로가기

# vs private in Class

category JavaScript/TypeScript 2021. 10. 27. 09:22

타입스크립트 핸드북을 읽다보면 클래스 파트에서 프라이빗 필드에 대해서 이렇게 설명하는 부분이 있다

이 문단 이후 # 에 대한 언급 없이 private문법에 대해서 소개를 이어나간다

그렇다면 이 둘의 차이점은 무엇일까..?

그것이 궁금해서 한 번 테스트 해보았다

하지만 # 구문에서 에러가 났는데 찾아보니 # 구문은 ECMAScript 2015 이상에서만 사용이 가능하다고 한다

지원 한다면서..

타입스크립트에서 이 문법을 사용할 수 있는 방법은 두 가지가 있는데

  • tsconfig.json을 이용해서 프로젝트 전체에 적용해야하는 경우이렇게 해주면 별 문제 없이 js로 빌드되어 브라우저에서 돌릴 수 있다
  • "compilerOptions": { "target": "ES6" },
  • 단일 파일을 대상으로 트랜스파일링할 때
  • npx tsc --target es6 handbook/class.ts

두 문법이 js에서 실제로 어떤 차이를 가지는지 궁금하기 때문에 두 번째 방법을 사용해서 차이점을 알아보자

TypeScript

class User {
    #username: string;
    private address = 'korea';
}

Javascript

var _username;
class User {
    constructor() {
        _username.set(this, void 0);
        this.address = 'korea';
    }
}
_username = new WeakMap();

알 수 있는 점은 다음과 같다

  1. private을 사용해서 선언한 필드는 ts 트랜스파일링시에만 privaty가 적용되고 실제 js로 들어가면 일반 필드와 같이 작동한다
  2. #을 이용한 필드는 빌드된 코드에서도 privaty를 유지되어 런타임 중에도 적용된다

어느것을 써야할까?

#은 js 안에서 문법적으로 좀 더 명확하게 privaty를 지키고 있다

하지만 굳이 설정을 건드려서 까지 #을 써야할까? 라는게 내 의견이다

설사 다른 문법을 사용하기 위해 트랜스파일링 버전을 올린다 하더라도 ts를 사용해서 코딩하고 있는 중이라면 ts단에서 걸러주는데 js에서 코드 낭비가 필요할까 싶다

저런거 몇 줄로 코드 낭비? 라고 생각할 수 있겠지만..

var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};

var _username;

class User {
    constructor(username) {
        _username.set(this, void 0);
        this.address = 'korea';
        __classPrivateFieldSet(this, _username, username);
    }
    introduce() {
        console.log(`Hello, my name is ${__classPrivateFieldGet(this, _username)}! and i'm living in ${this.address}`);
    }
}
_username = new WeakMap();
let user = new User("Jeremy Bearimy");
console.log(user);

#으로 선언된 필드를 인스턴스 내부에서 사용해야하는 경우에는 #필드를 사용하기 위한 보조 메서드가 더 붙는다

'JavaScript > TypeScript' 카테고리의 다른 글

d.ts // its corresponding type declarations.  (0) 2021.11.03
Mapped Type  (0) 2021.10.25
유틸리티 타입  (0) 2021.10.24
Generics  (0) 2021.03.12
Function  (0) 2021.03.11