[ 3D Web : Front_JavaScript ] 자스 핵심 개념 - Getter & Setter 정리.
∇ 자바스크립트에서의 Getter & Setter
목 차
1. 코딩에서 Getter & Setter 개념
2. JS에서 Getter & Setter
2-1 접근자 프로퍼티
2-2 Getter & Setter 주의점
2-3 Object.defineProperty
1. 코딩에서 Getter & Setter 개념
☆ " Getter 와 Setter " 는 '객체지향프로그램(OOP)'에서 사용되는 개념이며, 일종의 메서드라고 할 수 있습니다.
◎ 단어 그대로,
" Getter"는 속성(Property) 값을 반환하는 메서드이며,
" Setter"는 객체의 속성 값을 설정 & 변경하는 메서드. !
ex) 'user'라는 객체가 있을 경우,
- 보통이라면 user.name 으로 속성(프로퍼티)으로 바로 접근해서 값을 가져오거나 재설정할텐데
const user = {
name: '안다미로',
age: 30
}
console.log(user.name); // 안다미로
user.name = 'Andamiro';
위의 코드처럼 바로 속성에 접근하지 말고,
★ " getName()", "setName()" 메서드를 통해서
한번 경유해서 설정하도록 하는 기법이 Getter와 Setter 개념이라고 보면 됩니다.
const user = {
name: '안다미로',
age: 30,
// 객체의 메서드(함수)
getName() {
return user.name;
},
setName(value) {
user.name = value;
}
}
console.log(user.getName()); // 안다미로
user.setName('Andamiro');
§ Getter & Setter 활용하기.
☆ 굳이 번거롭게 Getter와 Setter를 만들어서 경유해서 접근하는 이유는 무엇일까요??
A. Getter & Setter를 사용하면 객체 내부 프로퍼티(속성)에 직접 접근하지 않기 때문에
객체의 '정보 은닉'을 가능하게 해주어 보안을 강화 할 수 있고, 코드의 안전성과 유지보수성을 높일 수 있음!
B. 속성에 옳지 못한 값을 넣으려고 할 때 미연에 방지 가능. ( if문을 함께 활용 )
ex) 위에 코드에 나이값을 1000이라는 말도 안되는 숫자를 넣으려고 하는 것을 막으려고 한다면
Setter 메서드를 통해서 값 입력을 한번 경유하도록 설정해서
메서드 내에서 if문을 통해서 필터링합니다.
const user = {
name: '안다미로',
age: 30,
getAge() {
return user.age;
},
setAge(value) {
// 만일 나이 값이 100 초과일 경우 바로 함수를 리턴해서 user.name이 재설정되지 않도록 필터링
if(value > 100) {
console.error('나이는 100을 초과할 수 없습니다.')
return;
}
user.name = value;
}
}
user.setAge(1000); // 나이는 100을 초과할 수 없습니다.
2. JS에서 Getter & Setter
- Getter와 Setter는 이론적인 개념으로만 보면
보통 위의 코드들처럼 " get프로퍼티명() " , " set프로퍼티명() " 형식으로 메스드 이름을 짓는 식으로 사용하지만
○ ES6로 들어서면서, JS에 Getter와 Setter를 간단하게 정의할 수 있는 문법이 별도로 추가되었습니다.
- > 객체 리터럴 안에서 속성 이름 앞에 " get " 또는 " set " 키워드만 붙여서
Getter와 Setter를 정의 가능해졌습니다.
[ 코드 간결성 & 가독성 증가 ]
const user = {
name: '안다미로',
age: 30,
// userName() 메서드 왼쪽에 get, set 키워드만 붙이면 알아서 Getter, Setter 로서 동작된다
get userName() {
return user.name;
},
set userName(value) {
user.name = value;
}
}
★ ★ 이때의 Getter와 Setter는 함수 호출 형식이 아닌, ' 일반 프로퍼티(속성) ' 처럼 사용 됩니다.
getter와 setter 메서드를 구현하면, 객체엔 userName이라는 가상의 프로퍼티(속성)이 생기는데
이 가상의 프로퍼티는 읽고 쓸수는 있지만 실제로는 존재하지 않는 프로퍼티입니다.
∇ 접근자 프로퍼티
- JS 상 '객체의 프로퍼티'는 크게 2가지 종류로 나룰 수 있습니다.
① 데이터 프로퍼티 ( data property )
= > 객체 내부에 저장된 실제 데이터 값.
== 우리가 일반적으로 '프로퍼티'라고 부르는 대상.
② 접근자 프로퍼티 ( accessor property )
= > 일반적인 프로퍼티와 달리, 키(key)와 값(value)을 가지지 않고
getter와 setter라는 함수를 가지는 특수한 프로퍼티.
==> ◎ 자바스크립트 객체 속성에 접근하듯이 접근자 프로퍼티를 호출하면,
함수 호출 문법이 아니더라도 getter & setter 함수가 호출되는 것과 동일.
☆정리하자면, Getter & Setter 함수 자체가 접근자 프로퍼티
let person = {
/* 데이터 프로퍼티 */
firstName: "John",
lastName: "Doe",
/* 접근자 프로퍼티 */
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(name) {
let names = name.split(" ");
this.firstName = names[0];
this.lastName = names[1];
}
};
console.log(person.firstName); // "Jane" 출력
console.log(person.lastName); // "Doe" 출력
console.log(person.fullName); // "John Doe" 출력
person.fullName = "Jane Doe"; // Setter 호출
∇ Getter & Setter 주의점.
◇ Getter만 선언할 시.
- Getter만 선언하고 Setter를 선언하지 않는다면,
아래 코드처럼, 값을 할당하려고 하면 에러가 발생하게 됩니다.
let user = {
get fullName() {
return `...`;
}
};
user.fullName = "Test"; // Error (프로퍼티에 getter 메서드만 있어서 에러가 발생합니다.)
◇ Setter 무한 루프.
- 데이터 프로퍼티명과 접근자 프로퍼티명이 동일할 경우,
Setter의 무한 루프에 빠져버리게 됩니다.
- 절대로, 접근자 프로퍼티의 이름을 중복되게 하면 안됩니다.
let user = {
name : 'inpa',
get name() {
return user.name;
},
set name(value) {
user.name = value;
}
}
// user 객체의 name 프로퍼티 값을 변경
user.name = 'inpa2';
-> 무한 루프의 발생 원인은 setter가 자기 자신을 계속해서 호출하기 때문입니다.
코드에서 person.name 에 값을 할당할때 setter 함수가 호출되게 됩니다.
그런데 setter 함수 내에서 this.name = value 를 통해 자기 자신에 값을 할당하고 있습니다.
이 행위는 곧, 자기 자신인 setter 접근자 프로퍼티 호출과 같은 행위이고
결국은 이 재귀 행위가 무한적으로 반복되어 무한 루프가 일어나는 것
이를 방지하고 싶다면,
- 접근자 프로퍼티명과 데이터 프로퍼티명을 다르게 하거나,
- 내부적으로 다른 변수에 값을 저장하도록 하면 됩니다.
const person = {
_name: "Inpa", // 데이터 프로퍼티명을 _name으로 변경
set name (value) {
this._name = value; // _name에 값을 할당
}
};
person.name = "Inpa2";
∇ Object.defineProperty
ES6가 나오기전 ES5에서는 Getter와 Setter를 구현하기 위해 Object.defineProperty() 메서드를 사용했었습니다.
Object.defineProperty()는 객체의 속성을 정의하고 수정하는 메서드로,
프로토타입 체인을 이용한 상속과 같이 고급 기능을 구현할 때 유용하게 사용될 수 있습니다.
하지만 코드의 가독성이 떨어지고 디버깅이 어려워질 수 있으므로,
실무 프로젝트에서 사용 빈도가 감소하고 있는 편입니다.
let person = {
firstName: "John",
lastName: "Doe"
};
// person 객체에 fullName 속성 추가
Object.defineProperty(person, "fullName", {
// getter 함수 정의
get: function() {
return this.firstName + " " + this.lastName;
},
// setter 함수 정의
set: function(name) {
let names = name.split(" ");
this.firstName = names[0];
this.lastName = names[1];
}
});
// fullName 속성에 접근하여 getter 함수 호출
console.log(person.fullName); // "John Doe" 출력
// fullName 속성에 접근하여 setter 함수 호출
person.fullName = "Jane Doe";
// firstName 속성과 lastName 속성이 setter 함수에 의해 업데이트되었는지 확인
console.log(person.firstName); // "Jane" 출력
console.log(person.lastName); // "Doe" 출력
// fullName 속성에 접근하여 getter 함수 호출
console.log(person.fullName); // "Jane Doe" 출력
'Front_End [JS기반] > 자바스크립트' 카테고리의 다른 글
[ 3D Web : Front_JavaScript ] 자바스크립트 label 문. (2) | 2024.11.17 |
---|---|
[ 3D Web : Front_JavaScript ] 변수 호이스팅 : var / let / const의 차이점 정리. (2) | 2024.11.04 |
[ 3D Web : Front_JavaScript ] 자스 핵심 개념 - 데이터 타입 ( Data Type ) (0) | 2024.11.03 |
[ 3D Web : Front_JavaScript ] 자바스크립트 문법 총 정리판 - [1] (1) | 2024.11.01 |
[ 3D Web : Front_JavaScript ] 자바스크립트 중요 개념 간략 모음집. (0) | 2024.11.01 |