Getter, Setter

접근자 프로퍼티 Getter/ Setter


들어가며

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 동작

callstack

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의 설명이 어렵게 느껴져 쉽고 복잡하지 않은 예시를 통해 설명해보면 좋지 않을까 하는 생각에서였습니다. 방어적 사용은 기본적인 부분이기 때문에 추가적인 학습이 필요하지만 쉬운 활용을 통해 쓰임에 친숙해지는 데 도움이 될 것으로 생각합니다.

고맙습니다. - 끄읕 -

참고문서


추천 글