---
title: Private class fields
slug: Web/JavaScript/Reference/Classes/Private_class_fields
tags:
  - Class
  - JavaScript
  - Private Field
translation_of: Web/JavaScript/Reference/Classes/Private_class_fields
---
<div>{{JsSidebar("Classes")}}</div>

<p>class 의 속성(property)들은 기본적으로 public 하며 class 외부에서 읽히고 수정될 수 있다. 하지만, ES2019 에서는 해쉬 <code>#</code> prefix 를 추가해 private class 필드를 선언할 수 있게 되었다.</p>

<h2 id="Syntax">Syntax</h2>

<pre class="notranslate">class ClassWithPrivateField {
  #privateField
}

class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world'
  }
}

class ClassWithPrivateStaticField {
  static #PRIVATE_STATIC_FIELD
}</pre>

<h2 id="Examples">Examples</h2>

<h3 id="Private_static_fields">Private static fields</h3>

<p>private 필드는 class 선언문 내부의 class 생성자(class constructor)에서 접근이 가능하다.</p>

<p>static 메소드에서만 static 변수들을 호출할 수 있다는 제약은 그대로 유지된다.</p>

<pre class="notranslate">class ClassWithPrivateStaticField {
  static #PRIVATE_STATIC_FIELD

  static publicStaticMethod() {
    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
  }
}

console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)</pre>

<p>Private static 필드는 class evaluation 시 class 생성자(class constructor)에 추가된다.</p>

<p>Private static 필드는 해당 필드를 선언한 class 에서만 접근할 수 있다.</p>

<p>이는 <code>this</code> 를 사용함에 있어 예상치 못한 동작을 야기할 수 있다.</p>

<pre class="notranslate">class BaseClassWithPrivateStaticField {
  static #PRIVATE_STATIC_FIELD

  static basePublicStaticMethod() {
    this.#PRIVATE_STATIC_FIELD = 42
    return this.#PRIVATE_STATIC_FIELD
  }
}

class SubClass extends BaseClassWithPrivateStaticField { }

let error = null

try {
  SubClass.basePublicStaticMethod()
} catch(e) { error = e}

console.assert(error instanceof TypeError)</pre>

<h3 id="Private_instance_fields">Private instance fields</h3>

<p>private 인스턴스 필드는 <strong># 이름 ('해쉬 이름' 으로 발음)</strong>,<strong> </strong>즉 <code>#</code> prefix 를 가진 식별자로 선언된다. <code>#</code> 은 그 이름 자체의 일부이며 선언과 접근 시에 모두 사용된다.</p>

<p>캡슐화(encapsulation) 는 언어로부터 강제된다(enforced by the language). 즉, scope 밖에서 <code>#</code> 이름에 접근하는 것은 syntax error 이다.</p>

<pre class="notranslate">class ClassWithPrivateField {
  #privateField

  constructor() {
    this.#privateField = 42
    this.#randomField = 444 // Syntax error
  }
}

const instance = new ClassWithPrivateField()
instance.#privateField === 42 // Syntax error</pre>

<h3 id="Private_Methods">Private Methods</h3>

<h4 id="Private_static_methods">Private static methods</h4>

<p><strong>private static 메소드</strong>는 public static 메소드처럼 인스턴스가 아닌 class 로부터 호출된다. 그리고 private static 필드처럼 class 선언문 내부에서만 접근 가능하다. </p>

<p>private static 메소드는 generator, async 그리고 async generator 함수가 될 수 있다.</p>

<pre class="notranslate">class ClassWithPrivateStaticMethod {
  static #privateStaticMethod() {
    return 42
  }

  static publicStaticMethod1() {
    return ClassWithPrivateStaticMethod.#privateStaticMethod();
  }

  static publicStaticMethod2() {
    return this.#privateStaticMethod();
  }
}

console.assert(ClassWithPrivateStaticMethod.publicStaticMethod1() === 42);
console.assert(ClassWithPrivateStaticMethod.publicStaticMethod2() === 42);</pre>

<p>이는 <code>this</code> 를 사용할 때 예상치 못한 동작을 발생시킬 수 있다. (이는 <code>this</code> binding rule 이 적용되기 때문이다.) 다음 예시에서 <code>Derived.publicStaticMethod2()</code> 를 호출할 때, <code>this</code> 는 class <code>Derived</code> (<code>Base</code> 가 아니라) 를 가리킨다. </p>

<pre class="notranslate">class Base {
  static #privateStaticMethod() {
    return 42;
  }
  static publicStaticMethod1() {
    return Base.#privateStaticMethod();
  }
  static publicStaticMethod2() {
    return this.#privateStaticMethod();
  }
}

class Derived extends Base {}

console.log(Derived.publicStaticMethod1()); // 42
console.log(Derived.publicStaticMethod2()); // TypeError</pre>

<h4 id="Private_instance_methods">Private instance methods</h4>

<p>private 인스턴스 메소드는 private 인스턴스 필드와는 다르게 class 인스턴스로부터 접근 가능하다.</p>

<pre class="notranslate">class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world'
  }

  getPrivateMessage() {
    return this.#privateMethod()
  }
}

const instance = new ClassWithPrivateMethod()
console.log(instance.getPrivateMessage())
// expected output: "hello worl​d"</pre>

<p>private 인스턴스 메소드는 generator, async 그리고 async generator 함수가 될 수 있다. private getter 와 setter 또한 가능하다:</p>

<pre class="notranslate">class ClassWithPrivateAccessor {
  #message

  get #decoratedMessage() {
    return `✨${this.#message}✨`
  }
  set #decoratedMessage(msg) {
    this.#message = msg
  }

  constructor() {
    this.#decoratedMessage = 'hello world'
    console.log(this.#decoratedMessage)
  }
}

new ClassWithPrivateAccessor();
// expected output: "✨hello worl​d✨"</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>



<p>{{Compat("javascript.classes.private_class_fields")}}</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields">Public class fields</a></li>
 <li><a href="https://rfrn.org/~shu/2018/05/02/the-semantics-of-all-js-class-elements.html">The Semantics of All JS Class Elements</a></li>
</ul>