java에서는 클래스를 만드는게 너무 당연한 일이었는데,
javascript에서는 한번도 직접 짜본적이 없었다.
그래서 javascript에서의 class사용을 주제로 정했다.
학습 후에는 class에 대한 두려움이 줄어들었고,
반드시 class를 만들어야 하는 케이스가 있다기보다는,
원하는 기능에 따라 일반 객체로 만들어도 되지만
class의 기능들이 쓰고싶으면 class로 만들면 되겠구나 생각했다.
get, set으로 만들수도 있고,
getName, setName처럼 함수를 만들어서 쓸수도 있다
! 내부변수는 _변수명으로 쓰는게 컨벤션이지만
안지켜도 제약이 없고
지켜도 외부에서 숨겨지지 않는다 (그건 아래의 #변수명)
내부변수명과 get 함수명을 동일하게 쓰면 오류가 난다
(this.name을 사용하면서 get name() 을 만들면 오류)
class Organization {
constructor(name) {
this._name = name;
}
//변수.name 로 값을 구함
get name() {
return this.#name;
}
//변수.getName()로 값을 구함
getName() {
return this.#name;
}
// 변수.name = 새 값
set name(aString) {
this.#name = aString;
}
// 변수.setName(새 값)
setName(aString) {
this.#name = aString;
}
}
export default function ClassTest() {
const orga = new Organization("로켓단");
const orgaName = orga.name;
const orgaName2 = orga.name(); //error!
const orgaName3 = orga.getName();
orga.name = '로켓다안';
orga.name('로케엣단'); //error!
orga.setName('로케엣다안');
}
객체형 필드를 private으로 만들어 직접 접근할 수 없도록 하고
객체 내부 값을 전달하는 getter로만 반환하도록 한다.
-> getter가 너무 늘어나거나, 객체용 메서드등을 사용하지 못하는 부작용
복제본 반환
-> 반환된 객체를 수정하면 class내부 객체도 수정될거라고 생각한 사용자는 당황할 수 있음
읽기전용으로 제공 (freeze).
강제로 수정시 strict모드에서 error발생하므로 사용자가 착각하지 않도록 함
-> 한번 freeze시켜버리면, setter도 작동을 안해버림
get info() {
// return this.#info; //1
// return {...this._info} //2
// return Object.freeze(this._info); //3
return Object.freeze({ ...this.#info }); //1+2+3
}
1 + 2 + 3을 조합하여
객체형 필드는 private으로 숨기고,
strict모드 사용, 복제본을 freeze걸어서 전달하면
setter를 사용해서만 저장하도록 하고
사용자가 수정 가능할거라고 착각하는것을 막을 수 있다.
인스턴스 없이 클래스에서 호출이 가능하고,
인스턴스에서는 호출이 불가능하다.
(필드, 함수 모두 적용 가능)
class Organization {
static _staticValue = 'static!!!';
...
}
export default function ClassTest() {
const orga = new Organization("로켓단");
const classStatic = Organization._staticValue; //static!!!
const instanceStatic = orga._staticVar; //undefined
}
기존에는 내부 사용 변수에 대해 _변수명으로 이름을 정하고
직접 가저다 쓰지 않는것이 컨벤션으로 이루어졌었는데,
javascript에도 private을 설정할 수 있게 되었다.
class Organization {
#name;
constructor(name) {
this.#name = name;
this._name = name;
}
//getter 생성하지 않음
}
export default function ClassTest() {
const orga = new Organization("로켓단");
const orgaName = orga._name; //로켓단
const orgaName2 = orga.#name; //error!
}
private 필드는 상속받은 클래스에서 직접 접근할 수 없다
class Base {
#name = "no name";
}
class Organization extends Base {
constructor(name) {
super();
this.#name = name; //error! - this.으로 부모의 #name에 접근 불가
}
}