[JS] 접근자 프로퍼티

hanganda23·2021년 3월 24일
0

모던JS 공부하기

목록 보기
3/4
post-thumbnail

자바스크립트 객체의 프로퍼티는 두 가지 종류로 나뉩니다.

  • 데이터 프로퍼티 (data property)
  • 접근자 프로퍼티 (accessor property)

접근자 프로퍼티의 본질은 함수인데 값을 획득하고 설정하는 역할을 담당합니다.
외부에서는 일반적인 프로퍼티처럼 사용합니다.

접근자 프로퍼티 만들기

접근자 프로퍼티는 getter(획득자)와 setter(설정자)로 구분됩니다.
객체 리터럴 안에서 get과 set으로 만듦니다.

let obj = {
	get fullName() {
    	// obj.fullName시 실행되는 코드
    },
  	set fullName(value) {
    	// obj.fullName = value 시 실행되는 코드
    }
}

활용

let user = {
	name: "John",
	surname: "Smith"
  
  	get fullName() {
    	return `${this.name} ${this.surname}`;
    }

	set fullName(value) {
     	[this.name,this.surname] = value.split(" ");
    }
};

alert(user.fullName); //John Smith

user.fullName = "yuno jang"
//name : yuno , surname : jang

이렇게 getter와 setter를 구현하면 객체엔 fullName이라는 '가상'의 프로퍼티가 생깁니다.
읽고 쓸 수 있지만 실제로는 존재하지 않습니다.

접근자 프로퍼티의 설명자

데이터 프로퍼티의 설명자와 접근자 프로퍼티의 설명자는 다릅니다.
접근자 프로퍼티는 value와 writable대신 get과 set이라는 함수가 있습니다.

  • get - 인수가 없는 함수로, 프로퍼티를 읽을 때 호출
  • set - 인수가 하나로, 프로퍼티에 값을 쓸 때 호출
  • enumable
  • configuable
Object.defineProperty(obj,'fullName',{
	get(){
      return this.name + this.surname;
    },
})

프로퍼티는 접근자 프로퍼티나 데이터 프로퍼티 둘 중 한 종류에만 속합니다.
따라서, get,set과 value를 동시에 설정하면 에러가 발생합니다.

활용 예제

getter와 setter를 실제 프로퍼티를 감싸는 래퍼 처럼 사용하면, 프로퍼티의 값을 통제할 수 있습니다.

let user = {
	get name() {
    	return this._name;
    }
  	set name(value) {
    	if(!value) {
        	alert('이름을 입력하세요');
          	return;
        }
      
      	this.name = value;
    }
}

실제 값은 별도 프로퍼티에 저장하고, setter에서 너무 짧아지는 것을 방지합니다.
또한, _name은 객체 내부에서만 활용하고 외부에서는 건드리지 않습니다.

호환성 유지를 위해 접근자 프로퍼티를 사용할 수도 있습니다.
유저 생성자 함수에서, 기존 age대신 birthday로 바꾸려합니다.
age보다는 birthday가 정확하고 편리하기 때문입니다.

그러나, 수정하면 기존 코드중 프로퍼티 age를 사용하는 코드도 수정해야 합니다.
해당 코드를 모두 수정하려하면, 찾기도 힘들고 시간이 오래 걸립니다.

age에 대한 getter/setter를 통해 문제를 해결합니다.

function User(name, birthday) {
  name,
  birthday,
  
  Object.defineProperty(this,"age"{
  	get(){
  		let todayYear = new Date().getFullYear();
    	return todayYear - this.birthday.getFullYear();
  	}                     
  	set (age) {
    	let todayYear = new Date().getFullYear();
      	this.birthday = todayYear - age;
    }
  });
      
}
profile
프론트엔드 취준생

0개의 댓글