본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

자바스크립트의 private

avatar
yceffort
2020-05-08 · 4분
4min
2020year
KOoriginal
javascript

이 글은 은닉을 향한 자바스크립트의 여정을 요약한 글입니다.

History

자바스크립트에서는 객체에 private 한 속성을 만들 수가 없었다. 그래서 보통 자바스크립트 개발자는 private한 것이다 라는 약속으로 _ prefix를 붙여서 사용하고는 했었다.

function Hello() {
  this.publicProp = 'public'
  this._privateProp = 'private'
}

물론 자바스크립트 개발자들은 _의 존재로 해당 속성을 건들지 말아야겠다는 것을 암묵적으로 공유했지만, 어디까지나 암묵적인 것일 뿐, 실제로는 밖에서 얼마든지 접근 할 수 있다.

좀 더 이 문제를 자바스크립트스럽게 해결하기 위해서는, 클로저를 활용하면 된다.

function Hello() {
  this.publicProp = 'public'
  const privateProp = 'private'

  _doWithPrivateProp = () => {
    // do something
  }
}

비록 this와 const가 짬뽕이 되면서, 가독성이 떨어지긴 하지만, 효과적으로 데이터를 격리 시켰다. 위와 같은 방법을 사용해서 메소드도 숨길 수 있다.

function Hello() {
  const publicProp = 'public'
  const privateProp = 'private'

  _doWithPrivateProp = () => {
    // ...
  }

  const publicMethod = () => {
    _doWithPrivateProp()
    // ...
  }

  return {
    publicProp,
    publicMethod,
  }
}

Symbol을 사용해 볼 수도 있다.

const privateMethodName = Symbol()
const privatePropName = Symbol()

class Hello {
  [privatePropName] = 'private'
  publicProp = 'public';

  [privateMethodName]() {
    // ...
  }

  publicMethod() {
    this[privateMethodName](this[privatePropName])
  }
}

Symbol은 생성될 때 마다 고유의 값을 가지므로, 외부에서는 이를 export하지 않는 이상 접근할 수 없다.

# 의 등장

해당 제안 내용은 여기에서 자세히 확인할 수 있다.

class Hello {
  #message = 'hello'
}

const hello = new Hell()
hello.#message
Uncaught SyntaxError: Private field '#message' must be declared in an enclosing class

private 하기 때문에 접근 할 수 없다는 메시지가 뜬다.

여기에서 #은 prefix이기 때문에 꼭 접근시에 #을 써야 한다.

class Hello {
  #message = 'hello'

  getMessage() {
    return this.message // 안됨
  }
}

상속을 받는다 하더라도 접근이 되지 않는다.

class Hello {
  #message = 'hello'

  getMessage() {
    return this.#message
  }
}

class Hi extends Hello {
  getHiMessage() {
    return this.#message
  }
}

const hi = new Hi()
hi.getHelloMessage() // Uncaught SyntaxError: Private field '#message' must be declared in an enclosing clas

추가로 모든 private 필드는 클래스 별로 독립된 고유한 스코프를 갖는다.

class Hello {
  #message = 'hello'

  getMessage() {
    return this.#message
  }
}

class Hi extends Hello {
  #message = 'hi'

  getHiMessage() {
    return this.#message
  }
}

const hi = new Hi()
const hello = new Hello()
console.log(hello.getMessage()) // hello
console.log(hi.getHiMessage()) // hi

타입스크립트에서는?

https://www.typescriptlang.org/docs/handbook/classes.html#ecmascript-private-fields https://www.typescriptlang.org/docs/handbook/classes.html#understanding-typescripts-private

위에서 언급한 # 문법과 더불어 (3.8부터) private 키워드 도 지원한다.

https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#ecmascript-private-fields

여기에 좋은 내용이 정리되어 있다.

  • Private 필드는 #으로 시작된다.
  • 모든 private 필드는 속한 클래스에서 고유한 스코프를 가지고 있다.
  • #은 타입스크립트의 public private과 함게 사용할 수 없다.
  • Private 필드는 클래스 밖에서 접근하거나 알아챌 수 없다. (JS도 마찬가지)

관련 글

  • #javascript

    javascript 일반 함수와 화살표 함수의 차이

    ES6에서부터 생긴 `arrow function`은 일반적으로 `()=>{}`의 모양을 하고 있으며, 동작도 비슷해보인다. 하지만 이 두 선언방식은 두가지 분명한 차이를 가지고 있다. 하지만 그전에 this를 알아야 한다.

    2020-05-19·3분
  • #javascript

    Javascript Execution Context

    들어가기에 앞서 더 좋고 제가 많이 참고한 글이 [여기](https://poiemaweb.com/js-execution-context)에 있습니다. 이글을 보시는게 낫습니다. ```toc tight: true, from-heading: 1 to-heading: 4 ``` # 자바스크립트 실행컨텍스트 이번 포스팅으로 자바스크립트 실행 컨텍스트에 대해 온...

    2020-06-26·17분
  • #javascript

    자바스크립트의 프록시

    IE를 주깁시다

    2021-03-12·5분
  • #javascript#v8#memory

    V8에서 관리되는 자바스크립트 변수

    V8 내부 코드를 자유롭게 읽을 수 있는 그날까지

    2022-04-21·수정 2022-04-26·10분

새 글을 놓치고 싶지 않으시다면

RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다.

← Back to the blogIssue on GitHub →