ES2019부터 자바스크립트에서도 #
prefix를 사용하면 private field를 선언할 수 있게 되었다.
프라이빗으로 선언된 경우 선언된 내부의 클래스에서만
접근이 가능하다.
class Person {
#name;
#age;
}
const person = new Person();
console.log(person.#name);
// Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class
클래스 외부에서 프라이빗으로 선언된 필드에 접근하려고 하니
문법 에러가 발생한다.
Private static field
class Iu {
static #name = '이지은';
#age = 30;
print(){
console.log(this.#name);
}
}
const iu = new Iu();
iu.print();
// Uncaught TypeError: Cannot read private member #name from an object whose class did not declare it at Iu.print
위 코드는 static private 필드로 선언한 #name을 print 메서드가 접근하려 하자 타입 에러가 발생했다.
에러의 원인은 static
으로 선언된 필드를 this
로 접근했기 때문이다.
class Iu {
static #name = '이지은';
#age = 30;
print(){
console.log(Iu.#name);
}
}
const iu = new Iu();
iu.print(); // 이지은
this
가 아닌 Iu.#name
으로 접근하면 에러가 해결된다.
private Method
private static 메서드
는 public static 메서드와 달리 인스턴스가 아닌, class에서 호출되며 해당 메서드가 선언된class 내부에서만 접근
할 수 있다.
class Iu {
static #name = '이지은';
#age = 30;
#print(){
console.log(Iu.#name);
}
}
const iu = new Iu();
iu.print();
// Uncaught TypeError: iu.print is not a function
private로 선언한 메서드를 iu 인스턴스가 호출하려 하자 타입 에러가 발생한다.
class Iu {
static #name = '이지은';
#age = 30;
#print(){
console.log(Iu.#name);
}
getPrint(){
return this.#print();
}
}
const iu = new Iu();
iu.getPrint(); // 이지은
해결 방법은 클래스 내부의 다른 메서드에서(프라이빗이 아닌) 호출시키는 방법이 있다.
getPrint 메서드는 프라이빗으로 선언된 print 메서드를 실행시켜 반환하고 있으므로
iu 인스턴스가 간접적으로 #print 메서드를 사용할 수 있게 된다.
프라이빗을 사용하는 이유 ?
프라이빗으로 선언하지 않았다면 외부에서 직접적으로 값을 변경시킬 수 있게 된다.
이처럼 외부에서 값이 변경되면 안되는 경우 캡슐화
를 통해 내부에서만 접근할 수 있도록 하기 위해 프라이빗을 사용하다.
참고 자료
MDN Private class fields