코딩/Javascript

[JS-중급편-OOP] 7.Getters and Setters

드리프트 2020. 12. 26. 12:50
728x170

 

 

지금까지 사용했던 데이터 속성을 넘어서 접근자 속성과 속성을 읽고 설정하는 방법을 완전히 제어 할 수있는 getters 및 setters의 역할에 대해 알아보십시오.

 

지금까지 작업 한 속성을 데이터 속성이라고합니다. 

 

다음은 이름을 지정하고 값을 할당하는 속성입니다.

 

let foo = {
	a: "Hello",
	b: "Monday"
}

 

값을 다시 읽으려면 값에 직접 액세스하기만 하면 됩니다.

 

console.log(foo.a);

 

이 속성에 값을 쓰는 것은 우리가 알고 있는 방법이 맞습니다.

 

foo.a = "Manic";

 

값을 설정하고 읽는 것 외에는 우리가 할 수있는 일이 별로 없습니다. 

 

이제 속성 읽기 및 속성 쓰기의 기능이 다음과 같으면 어떨까요?

 

  • 기존 문법을 유지하면서 속성 값을 읽고 쓸수 있기

  • 백그라운드에서 커스텀 코드를 실행할 수있는 기능 확보

위의 기능이 있다면 꽤 멋지겠죠?

 

결과적으로 우리는 이 모든 것을 할 수 있는 능력이 있습니다.

 

다음 섹션에서는 바로 그 능력들인 getters와 setters를 만나게 될 것입니다.

 

두 가지 속성 이야기

표면적으로 접근자 속성과 데이터 속성은 매우 비슷해 보입니다.

 

우리는 데이터 속성을 사용하여 속성을 읽고 쓸 수 있습니다.

 

theObj.storedValue = "Unique snowflake!"; // setting
console.log(theObj.storedValue); // reading

 

접근자 속성을 사용하면 거의 동일한 작업을 수행 할 수 있습니다.

 

myObj.storedValue = "Also a unique snowflake!"; // setting
console.log(myObj.storedValue); // reading

 

속성이 데이터 속성인지 접근자 속성인지 확인하기 위해 속성이 사용되는 방식을 보면 알 수 없습니다.

 

차이점을 알려면 속성이 실제로 정의 된 위치로 이동해야 합니다.

 

zorb 개체 내에 몇 가지 속성이 정의되어있는 다음 코드를 살펴봅시다.

 

let zorb = {
  message: "Blah",

  get greeting() {
    return this.message;
  },

  set greeting(value) {
    this.message = value;
  }
};

 

위 코드를 분석해 봅시다.

 

첫 번째는 일반적인 데이터 속성인 메시지입니다.

 

let zorb = {
  message: "Blah",
...
...

 

위에서 보듯이 단지 속성 이름과 값이기 때문에 데이터 속성이라는 것을 알고 있습니다.

 

다음 속성은 greeting이며, 과거에 본 어떤 속성처럼 보이지는 않습니다.

 

  get greeting() {
    return this.message;
  },

  set greeting(value) {
    this.message = value;
  }

 

message에서 본 것처럼 간단한 이름과 값 배열 대신 greeting 속성은 get 또는 set 키워드가 앞에 오는 두 가지 함수로 나뉩니다.

 

...

  get greeting() {
...

  set greeting(value) {
...

 

이러한 키워드 및 함수들은 일반적으로 각각 getter 및 setter라고 합니다.

 

그것들을 특별하게 만드는 것은 우리가 함수로써 greeting에 액세스하지 않는다는 것입니다.

 

단지 이전처럼 속성처럼 액세스합니다.

 

zorb.greeting = "Hola!";
console.log(zorb.greeting);

 

뭔가 헷갈리시죠?

 

getter와 setter 수준에서 다음에 더 자세히 살펴 보겠습니다.

 

 

Getter 와 Setter 맛보기

지금까지 우리가 알고있는 것은 getter와 setter는 속성처럼 작동하는 함수일 뿐입니다.

 

접근자 속성 zorb.greeting 처럼 접근자 속성으로 읽으려고하면 이때 getter 함수가 호출됩니다.

 

...
  get greeting() {
    return this.message;
  },
...

 

마찬가지로 zorb.greeing = "Hola!" 처럼 접근자 속성으로 새 값을 설정하면 setter 함수가 호출됩니다.

 

...
  set greeting(value) {
    this.message = value;
  }
...

 

getter 및 setter의 모든 기능은 속성을 읽거나 쓸 때 실행할 수있는 코드에 있습니다.

 

내부적으로 함수를 다루기 때문에 원하는 코드를 실행할 수 있습니다.

 

zorb 예제에서는 greeting getter 및 setter를 사용하여 데이터 속성이 수행하는 작업을 거의 모방했습니다.

 

값을 설정할 수 있으며 방금 설정 한 값을 다시 읽을 수 있습니다.

 

다음 예제는 getter와 setter의 좀더 자세한 예제입니다.

 

Shout Generator

다음은 지정한 메시지가 모두 대문자로 바뀌는 예입니다.

 

var shout = {
  _message: "HELLO!",

  get message() {
    return this._message;
  },

  set message(value) {
    this._message = value.toUpperCase();
  }
};

shout.message = "This is sparta!";
console.log(shout.message);

 

setter에서 메시지 속성 값을 저장하는 과정에서 모든 String 객체가 제공하는 toUpperCase 메서드 덕분에 입력된 값을 모두 대문자로 저장합니다.

 

저장한 메시지를 다시 읽으려고 할 때는 setter에서 설정된 대로 모두 대문자로 나타납니다.

 

 

 

Logging Activity

다음 예제에는 모든 사용자 이름을 기록하는 superSecureTerminal 객체가 있습니다.

 

var superSecureTerminal = {
  allUserNames: [],
  _username: "",

  showHistory() {
    console.log(this.allUserNames);
  },

  get username() {
    return this._username;
  },

  set username(name) {
    this._username = name;
    this.allUserNames.push(name);
  }
}

 

위 코드의 로깅 방식은 각 사용자 이름이 allUserNames 배열에 저장되고 showHistory 함수가 저장된 사용자 이름을 화면에 표시하는 방식입니다.

 

실제로 이 코드를 테스트 해 보겠습니다.

 

과거에 했던 것과는 다른 방식으로 superSecureTerminal에 액세스 할 것입니다. 객체를 생성하고 접근하는 방식입니다.

 

var myTerminal = Object.create(superSecureTerminal);
myTerminal.username = "Michael Gary Scott";
myTerminal.username = "Dwight K. Schrute";
myTerminal.username = "Creed Bratton";
myTerminal.username = "Pam Beasley";

myTerminal.showHistory();

 

superSecureTerminal 객체를 기반으로 하는 myTerminal이라는 새 객체를 만듭니다.

 

새로 만든 myTerminal 객체로 모든 작업을 수행합니다.

 

 

속성 값 유효성 검사

 

마지막으로 살펴볼 예는 setter가 전송 된 값에 대해 몇 가지 유효성 검사를 하는 예입니다.

 

let person = {
  _name: "",
  _age: "",

  get name() {
    return this._name;
  },

  set name(value) {
    if (value.length > 2) {
      this._name = value;
    } else {
      console.log("Name is too short!");
    }
  },

  get age() {
    return this._age;
  },

  set age(value) {
    if (value < 5) {
      console.log("Too young!");
    } else {
      this._age = value;
    }
  },

  get details() {
    return "Name: " + this.name + ", Age: " + this.age;
  }
}

 

_name과 _age 속성 모두에서 입력한 값을 사전 체크합니다.

 

제공하는 이름이 2 글자 미만인 경우 경고가 표시됩니다.

 

나이가 5 세 미만인 경우 경고도 표시됩니다.

 

속성에 할당 한 값이 좋은지 여부를 확인할 수 있다는 것은 getter와 setter가 제공하는 최고의 기능 중 하나 일 것입니다.

 

 

결론

자바스크립트 코드를 짤때 데이터 속성으로 접근하느냐, 접근자 속성으로 접근하느냐는 필요에 따라 다릅니다.

 

좀더 유연하게 상황을 봐서 그때 그때 좋은 방식으로 결정하면 됩니다.

 

다음편에서는 자바스크립트 객체에 대해 좀더 심도 있게 알아 보겠습니다.

 

그리드형