property는 어떤 값을 나타내고, 이 값이 다른 값과 연관을 가지고 있을때 property라고 부른다.
예를 들어 문자열에는 length라는 property가 있는데, 이 프로퍼티는 문자열 안에 있는 문자의 양을 정수로 나타낸 값을 가지고 있다.
property는 보통 데이터 구조와 연관된 속성을 나타낸다. property에는 2가지 종류가 있다.
접근자란 객체 지향 프로그래밍에서 객체가 가진 프로퍼티 값을 객체 바깥에서 읽거나 쓸 수 있도록 제공하는 메서드를 말한다. 객체의 프로퍼티를 객체 바깥에서 직접 조작하는 행위는 데이터의 유지 보수성을 해치는 주요한 원인이다.
접근자 프로퍼티는 getter(획득자)와 setter(설정자) 메서드로 표현한다.
객체 리터럴 안에서 getter와 setter 메서드는 get과 set으로 나타낼 수 있다.
let obj = {
get propName() {
// getter, obj.propName을 실행할 때 실행되는 코드
},
set propName(value) {
// setter, obj.propName = value를 실행할 때 실행되는 코드
}
};
obj.propName
을 사용해 프로퍼티를 읽으려고 할 때 실행된다. obj.propName = value
으로 프로퍼티에 값을 할당할 때 실행된다.let user = {
name : "john",
surname: "smith",
get fullName() {
return `${this.name} ${this.surname}`'
}
};
alert(user.fullName); // John Smith
바깥 코드에서 접근자 프로퍼티를 일반 프로퍼티처럼 사용할 수 있다.
접근자 프로퍼티는 이런 아이디어에서 출발했다. 접근자 프로퍼티를 사용하면
함수처럼 호출하지 않고, 일반 프로퍼티에서 값에 접근하는 것처럼 평범하게 user.fullName을 사용해 프로퍼티 값을 얻을 수 있다.
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
// 주어진 값을 사용해 set fullName이 실행됩니다.
user.fullName = "Alice Special"
alert(user.fullName); // Alice Special
alert(user.name); // Alice
alert(user.surname); // Special
이렇게 getter와 setter 메서드를 구현하면 객체엔 fullName이라는 '가상'의 프로퍼티가 생긴다. 가상의 프로퍼티를 읽고 쓸 순 있지만 실제로는 존재하지 않는다.
접근자 프로퍼티엔 설명자 value와 writable가 없는 대신에 get과 set이라는 함수가 있습니다.
따라서 접근자 프로퍼티는 다음과 같은 설명자를 갖는다.
아래와 같이 defineProperty에 설명자 get과 set을 전달하면 fullName을 위한 접근자를 만들 수 있다.
let user = {
name: "John",
surname: "Smith"
};
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
alert(user.fullName); // John Smith
for(let key in user) alert(key); // name, surname
일반적으로 이름을 읽고 수정하는 객체는 다음과 같이 이름을 수정하는 메서드 setName()을 포함하고 있다.
let user = {
name: '',
setName(value) {
if (value.length < 4) {
alert("입력하신 값이 너무 짧습니다. 네 글자 이상으로 구성된 이름을 입력하세요.");
return;
}
this.name = value;
}
};
user.setName("Pete");
alert(user.name); // Pete
user.setName(""); // 너무 짧은 이름을 할당하려 함
그러나 getter와 setter를 '실제' 프로퍼티 값을 감싸는 래퍼 처럼 사용하면, 메서드를 새로 만드는 일 없이 프로퍼티 값을 원하는 대로 통제할 수 있다.
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("입력하신 값이 너무 짧습니다.");
return;
}
this._name = value;
}
};
user.name = "pete";
alert(user.name); // pete
user.name = "";
user의 이름은 _name에 저장되고, 프로퍼티에 접근하는 것은 getter(user.name)과 setter(user.name= value)를 통해 이루어진다.