diff options
Diffstat (limited to 'files/ko/web/javascript/reference/classes/private_class_fields/index.html')
-rw-r--r-- | files/ko/web/javascript/reference/classes/private_class_fields/index.html | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/files/ko/web/javascript/reference/classes/private_class_fields/index.html b/files/ko/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..ea5508ab27 --- /dev/null +++ b/files/ko/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,201 @@ +--- +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 world"</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 world✨"</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> |