들어가며
Object의 객체의 쓰임과 활용에 대해 학습을 하던 중 Getter와 Setter를 접하였습니다. 접근자 프로퍼티라는 이 요소들이 바로 이해되지 않아 여러 가지 내용을 찾아봤었는데요. 그중 이해하는 데 도움이 되었던 내용을 정리하였습니다.
Getter
const obj = {
num: 0,
get getNum() {
return this.num;
},
};
console.log(obj.getNum);
// 0
Getter에서는 객체 내에서 값을 얻고(get), 그 얻은 값을 반환(return)합니다.
Setter
const obj = {
num: 0,
get getNum() {
return this.num;
},
set ComputedNum(value) {
this.num = value * 2;
},
};
obj.ComputedNum = 5;
console.log(obj.getNum);
// 10;
Setter에서는 객체 내에서 값을 설정(set)하기 때문에 항상 인자(value)를 받아야 합니다.
그럼 왜, 언제 사용하는 것일까요?
MDN 문서 Getter/ Setter에 자세하게 나와있지만 저는 방어적인 코드를 만들 때 사용할 수 있다고 이해하였습니다. 아래 예시 코드가 있습니다.
Class 선언으로 객체를 생성합니다. get/ set을 활용할 수 있는 생성자함수입니다.
class MiddleSchooler {
// 객체 정의
constructor(name, grade) {
this.name = name;
this.grade = grade;
}
}
// 객체 생성
const middleSchool = new MiddleSchooler('John', 0);
console.log(middleSchool.grade);
// 0
grade에 0을 할당하였습니다. 중학생 학년에 0 이하나 4 이상의 숫자는 논리적으로 맞지 않습니다. 그래서 범위를 제한할 수 있는 방어 코드가 필요합니다. 이때 객체에 접근할 수 있는 get/ set을 활용할 수 있습니다.
Call Stack
class MiddleSchooler {
// 객체 정의
constructor(name, grade) {
this.name = name;
this.grade = grade;
}
// getter
get grade() {
return this.grade;
}
// setter
set grade(value) {
this.grade = value;
}
}
// 객체 생성
const middleSchool = new MiddleSchooler('John', 0);
코드를 작성하는 중 call stack 오류가 발생하였습니다. 이는 get/ set이 정의되면 값을 업데이트하는 것이 아니라 호출을 하기 때문입니다. call stack 오류 (console 창에서 확인)
Get/ Set 동작
this.grade(빨강)는 get을 호출하고, grade(노랑)는 set을 호출합니다.
다시 말해 set을 보면 값인 value가 set()을 호출하고 set()은 value를 할당합니다. 그럼 다시 value가 set을 호출할 것이고 set()은 또 다시 value를 할당할 것입니다. 이 작업이 무한 반복되기 때문에 call stack 오류가 발생하는 것입니다. 따라서 프로퍼티 명을 다르게 써야 하는데 주로 앞에 _(언더바)를 붙입니다.
Getter/ Setter 활용
get/ set의 프로퍼티 명도 변경하고 value의 조건도 정의하여 코드를 완성하였습니다. 코드 확인
class MiddleSchooler {
// 객체 정의
constructor(name, grade) {
this.name = name;
this.grade = grade;
}
// getter
get grade() {
return this._grade;
}
// setter
set grade(value) {
this._grade = value <= 0 || value > 3 ? '학년을 확인해주세요.' : value;
}
}
// 객체 생성
const middleSchool = new MiddleSchooler('John', 4);
// 결과
console.log(middleSchool.grade);
// 학년을 확인해주세요.
마치며
이 프로퍼티를 왜, 언제 사용할 수 있나에 대해 MDN의 설명이 어렵게 느껴져 쉽고 복잡하지 않은 예시를 통해 설명해보면 좋지 않을까 하는 생각에서였습니다. 방어적 사용은 기본적인 부분이기 때문에 추가적인 학습이 필요하지만 쉬운 활용을 통해 쓰임에 친숙해지는 데 도움이 될 것으로 생각합니다.
고맙습니다. - 끄읕 -