es6의 class 문법에는 private data를 직접 지정할 수 있는 기능이 제공되지 않는다. 때문에 private data로 쓰고자 하는 변수는 우회적으로 관리하여야 하는데, 그 방법들을 소개한다.
1. naming convention _
변수에 접두어 _를 붙이면 private data로 간주하기로 하는 규칙을 정하는 방법.
실질적인 접근제한은 전혀 이뤄지지 않는다.
2. constructor 내부에서 할당
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classCount{
constructor(_count) {
const methods = {
inc() { _count += 1; return _count; },
dec() { _count -= 1; return _count; },
getScore() { return _count; },
get score() { return _count; },
set score(v) { _count = v; }
};
Object.assign(this, methods);
}
}
const test = new Count(0);
console.log(test.inc()); // 1
console.log(test.inc()); // 2
console.log(test.dec()); // 1
console.log(test.getScore()); // 1
이 방법은 constructor 내부에서만 접근 가능한 변수를 사용하는 모든 메소드를 constructor에서 정의하고, 이를 그대로 인스턴스에 반영하기 위해 Object.assign 메소드를 활용한다. 이로써 _count 변수는 값을 외부에 노출하지 않고 오직 내부에서만 접근이 가능해진다.
그러나 이는 메소드를 인스턴스에 직접 할당하는 것이므로, 메소드를 상속받아 사용하겠다는 Class의 본질적인 사용 의미를 무색케 만드는 셈이다. 또한 delete로 메소드를 삭제할 수도 있고, 메소드를 override가 아닌 완전한 대체를 할 수도 있다.
뿐만 아니라 getter/setter는 별도의 데이터(this.score)에 접근하는 등의 문제도 있다 (원인은 모르겠다. 아시는 분은 댓글 부탁드립니다).
1
2
3
4
console.log(test.score); // 0
test.score = 20;
console.log(test.score); // 20
console.log(test.getScore()); // 1
한편 method를 모두 this.constructor.prototype에 할당한다면 _count 변수를 공통으로 사용하는 결과가 되므로, 각 인스턴스들의 독립성이 보장되지 않게 되어 마찬가지로 Class를 사용하는 의미가 없다.