Skip to content

7. 객체(Object)


1. 키워드

  • 객체(Object)
  • 프로퍼티(Property)와 메서드(Method)
  • 인스턴스(Instance)
  • 프로토타입(Prototype)
  • 상속(Inheritance)


2. 객체의 개념

1) 객체란?

  • 객체란 실생활에서 우리가 인식할 수 있는 사물로 이해할 수 있다.


2) 자바스크립트 객체

  • 자바스크립트의 기본 타입은 객체이다.


  • 객체란 이름과 값으로 구성된 프로퍼티의 정렬되지 않은 집합이다.
  • 프로퍼티의 값으로 함수가 올 수도 있는데, 이러한 프로퍼티를 메서드라고 한다.


var cat = "나비"; // 일반적인 변수의 선언
// 객체도 많은 값을 가지는 변수의 하나임.
var kitty = { name: "나비", family: "코리안 숏 헤어", age: 1, weight: 0.1 };

cat; // 나비
kitty.name; // 나비


  • 자바스크립트에서는 숫자, 문자열, 불리언, undefined 타입을 제외한 모든 것이 객체이다.
  • 하지만 숫자, 문자열, 불리언과 같은 원시 타입은 값이 정해진 객체로 취급되어, 객체로서의 특징도 함께 가지게 된다.


3) 객체의 프로퍼티 참조

  • 자바스크립트에서 객체의 프로퍼티를 참조하는 방법은 다음과 같다.


객체이름.프로퍼티이름;
또는;
객체이름["프로퍼티이름"];
var person = {
  name: "홍길동", // 이름 프로퍼티를 정의함.
  birthday: "030219", // 생년월일 프로퍼티를 정의함.
  pId: "1234567", // 개인 id 프로퍼티를 정의함.
  fullId: function () {
    // 생년월일과 개인 id를 합쳐서 주민등록번호를 반환함.
    return this.birthday + this.pId;
  },
};

person.name; // 홍길동
person["name"]; // 홍길동


4) 객체의 메서드 참조

  • 자바스크립트에서 객체의 메서드를 참조하는 방법은 다음과 같다.


객체이름.메서드이름();
var person = {
  name: "홍길동",
  birthday: "030219",
  pId: "1234567",
  fullId: function () {
    return this.birthday + this.pId;
  },
};

person.fullId(); // 0302191234567
person.fullId; // function () { return this.birthday + this.pId; }


Note

  • 메서드를 참조할 때 메서드 이름 뒤에 ()(괄호)를 붙이지 않으면, 메서드가 아닌 프로퍼티 그 자체를 참조하게 된다.
  • 따라서 괄호를 사용하지 않고 프로퍼티 그 자체를 참조하게 되면 해당 메서드의 정의 그 자체가 반환된다.


3. 객체의 생성

  • 자바스크립트에서 객체를 생성하는 방법은 다음과 같다.


1] 리터럴 표기(Literal Notation)를 이용한 방법

2] 생성자 함수(Constructor Function)를 이용한 방법

3] Object.create() 메서드를 이용한 방법


  • 위와 같은 방법으로 생성되어 메모리에 대입된 객체를 인스턴스라고 한다.


1) 리터럴 표기를 이용한 객체의 생성

  • 자바스크립트에서 객체를 생성하는 가장 쉬운 방법은 리터럴 표기를 이용하는 방법이다.


var 객체이름 = {
 프로퍼티1이름: 프로퍼티1의값,
 프로퍼티2이름: 프로퍼티2의값,
 ...
}


  • 각각의 프로퍼티는 이름과 값을 :(콜론)으로 연결하고, ,(쉼표)를 사용해 다른 프로퍼티와 구분한다.
  • 프로퍼티의 이름으로는 자바스크립트의 식별자나 문자열을 사용할 수 있다.


var kitty = {
  name: "나비",
  family: "코리안 숏 헤어",
  age: 1,
  weight: 0.1,
};

document.write(
  "우리 집 새끼 고양이의 이름은 " +
    kitty.name +
    "이고, 종은 " +
    kitty.family +
    "입니다."
);


2) 생성자를 이용한 객체의 생성

  • new 연산자를 사용하여 객체를 생성하고 초기화할 수 있다.
  • 이때 사용되는 메서드를 생성자라고 하며, 이 메서드는 새롭게 생성되는 객체를 초기화하는 역할을 한다.
  • 자바스크립트는 원시 타입을 위한 생성자를 미리 정의하여 제공한다.


var day = new Date(); // new 연산자를 사용하여 Date 타입의 객체를 생성함.
document.write("올해는 " + day.getFullYear() + "년입니다.");


  • 위의 예제처럼 자바스크립트에서 제공하는 생성자를 사용할 수도 있으며, 사용자가 직접 객체 생성자 함수를 작성하여 사용할 수도 있다.


3) Object.create() 메서드를 이용한 객체의 생성

  • Object.create() 메서드를 이용하여 객체를 생성할 수도 있다.
  • Object.create() 메서드는 지정된 프로토타입 객체와 프로퍼티를 가지고 새로운 객체를 만들어 준다.
  • 따라서 이 메서드를 이용하면 사용자가 프로토타입 객체를 직접 명시할 수 있으므로, 상당히 유용하게 사용된다.


Object.create(프로토타입객체[, 새로운객체의프로퍼티1, 새로운객체의프로퍼티2, ...]);


  • Object.create() 메서드의 첫 번째 인수로는 프로토타입으로 사용할 객체를 전달한다.
  • 두 번째 인수로는 새로운 객체의 추가할 프로퍼티 정보를 전달한다.


var obj = Object.create(null, {
  // null 프로토타입을 사용하여 새로운 객체를 만들고
  x: { value: 100, enumerable: true }, // x좌표를 나타내는 열거할 수 있는 프로퍼티와
  y: { value: 200, enumerable: true }, // y좌표를 나타내는 열거할 수 있는 프로퍼티를 추가함.
});

obj.x; // x좌표
obj.y; // y좌표

Object.getPrototypeOf(obj); // 객체의 프로토타입을 반환해 줌.


4. 프로토타입

1) 상속

  • 상속이란 새로운 클래스에서 기존 클래스의 모든 프로퍼티와 메서드를 사용할 수 있는 것을 의미한다.


  • 상속을 통해 새로운 프로그램의 요구에 맞게 기존 클래스를 수정하여 재사용할 수 있다.
  • 또한, 클래스 간의 종속 관계를 형성함으로써 객체의 관계를 조직화할 수 있는 장점이 있다.
  • 따라서 이러한 상속은 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나가 된다.


  • 하지만 C#이나 C++과 같은 클래스 기반의 객체 지향 언어와는 달리 자바스크립트는 프로토타입 기반의 객체 지향 언어이다.
  • 프로토타입 기반이기 때문에 상속의 개념이 클래스 기반의 객체 지향 언어와는 약간 다르다.
  • 자바스크립트에서는 현재 존재하고 있는 객체를 프로토타입으로 사용하여, 해당 객체를 복제하여 재사용하는 것을 상속이라고 한다.


2) 프로토타입

  • 자바스크립트의 모든 객체는 프로토타입이라는 객체를 가지고 있다.
  • 모든 객체는 그들의 프로토타입으로부터 프로퍼티와 메서드를 상속받는다.
  • 이처럼 자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체들로부터 상속을 받으며, 이때 상속되는 정보를 제공하는 객체를 프로토타입이라고 한다.


3) 프로토타입 체인

  • 자바스크립트에서는 객체 이니셜라이저를 사용해 생성된 같은 타입의 객체들은 모두 같은 프로토타입을 가진다.
  • 또한, new 연산자를 사용해 생성한 객체는 생성자의 프로토타입을 자신의 프로토타입으로 상속받는다.


var obj = new Object(); // 이 객체의 프로토타입은 Object.prototype입니다.
var arr = new Array(); // 이 객체의 프로토타입은 Array.prototype입니다.
var date = new Date(); // 이 객체의 프로토타입은 Date.prototype입니다.


  • 하지만 Object.prototype 객체는 어떠한 프로토타입도 가지지 않으며, 아무런 프로퍼티도 상속받지 않는다.
  • 또한, 자바스크립트에 내장된 모든 생성자나 사용자 정의 생성자는 바로 이 객체를 프로토타입으로 가진다.


var date = new Date(); // 이 객체는 Date.prototype 뿐만 아니라 Object.prototype도 프로토타입으로 가집니다.


  • 위와 같이 프로토타입이 상속되는 가상의 연결 고리를 프로토타입 체인이라고 한다.
  • Object.prototype 객체는 이러한 프로토타입 체인에서도 가장 상위에 존재하는 프로토타입이다.
  • 따라서 자바스크립트의 모든 객체는 Object.prototype 객체를 프로토타입으로 상속받는다.


4) 프로토타입의 생성

  • 프로토타입을 생성하는 가장 기본적인 방법은 객체 생성자 함수를 작성하는 것이다.
  • 생성자 함수를 작성하고 new 연산자를 사용해 객체를 생성하면, 같은 프로토타입을 가지는 객체들을 생성할 수 있다.


function Dog(color, name, age) {
  // 개에 관한 생성자 함수를 작성함.
  this.color = color; // 색에 관한 프로퍼티
  this.name = name; // 이름에 관한 프로퍼티
  this.age = age; // 나이에 관한 프로퍼티
}

var myDog = new Dog("흰색", "마루", 1); // 이 객체는 Dog라는 프로토타입을 가짐.

document.write(
  "우리 집 강아지는 " +
    myDog.name +
    "라는 이름의 " +
    myDog.color +
    " 털이 매력적인 강아지입니다."
);


5) 객체에 프로퍼티 및 메서드 추가

  • 이미 생성된 객체에 새로운 프로퍼티나 메서드를 추가하는 방법은 다음과 같다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

myDog.family = "시베리안 허스키"; // 품종에 관한 프로퍼티를 추가함.
myDog.breed = function () {
  // 털색을 포함한 품종을 반환해 주는 메소드를 추가함.
  return this.color + " " + this.family;
};

document.write("우리 집 강아지는 " + myDog.breed() + "입니다.");


  • 위의 예제에서 새롭게 추가된 weight 프로퍼티와 breed() 메서드는 오직 myDog 인스턴스에만 추가된다.
  • 이미 생성된 다른 Dog 객체나 차후에 생성되는 어떠한 다른 Dog 객체에도 추가되지 않는다.


6) 프로토타입에 프로퍼티 및 메서드 추가

  • 프로토타입에 새로운 프로퍼티나 메서드를 추가하는 것은 객체에 추가할 때와는 다른 방법을 사용해야 한다.
  • 프로토타입의 경우에는 생성자 함수에 직접 추가해야만 이후에 생성되는 모든 다른 객체에도 적용할 수 있다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
  this.family = "시베리안 허스키"; // 프로토타입에 프로퍼티를 추가할 때에는 기본값을 가지게 할 수 있음.
  this.breed = function () {
    return this.color + " " + this.family;
  };
}

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("갈색", "콩이", 3);

document.write(
  "우리 집 강아지는 " +
    myDog.family +
    "이고, 친구네 집 강아지도 " +
    hisDog.family +
    "입니다."
);


7) prototype 프로퍼티

  • prototype 프로퍼티를 이용하면 현재 존재하고 있는 프로토타입에 새로운 프로퍼티나 메서드를 손쉽게 추가할 수 있다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

// 현재 존재하고 있는 Dog 프로토타입에 family 프로퍼티를 추가함.
Dog.prototype.family = "시베리안 허스키";
// 현재 존재하고 있는 Dog 프로토타입에 breed 메소드를 추가함.
Dog.prototype.breed = function () {
  return this.color + " " + this.family;
};

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("갈색", "콩이", 3);

document.write(
  "우리 집 강아지는 " +
    myDog.family +
    "이고, 친구네 집 강아지도 " +
    hisDog.family +
    "입니다."
);
document.write("우리 집 강아지의 품종은 " + myDog.breed() + "입니다.<br>");
document.write("친구네 집 강아지의 품종은 " + hisDog.breed() + "입니다.");


5. 객체 다루기

1) this 키워드

  • 자바스크립트에서 this 키워드는 해당 키워드가 사용된 자바스크립트 코드 영역을 포함하고 있는 객체를 가리킨다.


  • 예를 들어, 메서드 내부에서 사용된 this 키워드는 해당 메서드를 포함하고 있는 객체를 가리킨다.
  • 또한, 객체 내부에서 사용된 this 키워드는 객체 그 자신을 가리킨다.
  • 이러한 this는 변수가 아닌 키워드이므로, 사용자가 임의로 가리키는 값을 바꿀 수 없다.


2) 객체 프로퍼티의 삭제

  • 자바스크립트에서 객체의 프로퍼티를 참조하는 방법은 다음과 같다.


객체이름.프로퍼티이름;
또는;
객체이름["프로퍼티이름"];


  • 자바스크립트에서는 delete 키워드를 사용하여 객체의 프로퍼티를 삭제할 수 있다.


delete 객체이름.프로퍼티이름;


  • delete 키워드를 사용하여 프로퍼티를 삭제하면, 프로퍼티의 값뿐만 아니라 프로퍼티 그 자체도 삭제된다.
  • 이 키워드는 본래 객체의 프로퍼티만을 삭제하기 위해 만들어졌기 때문에 함수나 변수에 사용하면 아무런 동작도 하지 않는다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

delete myDog.age; // age 프로퍼티를 삭제함.

// age 프로퍼티가 삭제되었기 때문에 undefined를 출력함.
document.write("우리집 강아지의 나이는 " + myDog.age + "입니다.");


3) 객체 프로퍼티의 순회

  • 자바스크립트에서는 for/in 문을 사용하여 객체의 모든 프로퍼티를 순회할 수 있다.
  • for/in 문은 객체의 모든 열거할 수 있는 프로퍼티를 손쉽게 순회할 수 있도록 해준다.


  • 객체의 프로퍼티를 순회하는 방법으로는 for/in 문 이외에도 다음과 같은 메서드를 사용할 수 있다.


1] Object.keys()

2] Object.getOwnPropertyNames()


  • Object.keys() 메서드는 해당 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티의 이름을 배열에 담아 반환한다.
  • Object.getOwnPropertyNames() 메서드는 해당 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환한다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

// color 프로퍼티의 enumerable 속성을 false로 설정함.
Object.defineProperty(myDog, "color", { enumerable: false });

// 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티 이름을 배열에 담아 반환함.
document.write(Object.keys(myDog) + "<br>"); // name, age

// 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환함.
document.write(Object.getOwnPropertyNames(myDog)); // color, name, age


4) 객체간의 비교

  • 자바스크립트에서 별개의 두 객체는 프로퍼티의 값이 모두 같아도, 절대로 같다고 말할 수 없다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("흰색", "마루", 1); // 모든 프로퍼티의 값이 모두 같은 객체를 생성함.

document.write((myDog == hisDog) + "<br>"); // false
document.write((myDog === hisDog) + "<br>"); // false

var herDog = hisDog; // hisDog 객체를 변수 herDog에 대입함.

document.write((hisDog == herDog) + "<br>"); // true
document.write((hisDog === herDog) + "<br>"); // true


  • 위의 예제에서 myDoghisDog 객체는 가지고 있는 프로퍼티의 값이 모두 같다.
  • 하지만 이 두 객체는 별개의 객체이므로, == 연산자와 === 연산자로 비교해도 모두 false를 반환한다.


  • 위의 예제에서는 변수 herDoghisDog 객체를 대입한다.
  • 이렇게 객체를 대입한 변수를 객체 레퍼런스라고 하며, 이제부터 변수 herDoghisDog 객체를 가리키게 된다.
  • 즉, 객체 레퍼런스는 객체 자체를 저장하는 것이 아니라, 객체가 위치한 주소를 저장하는 것이다.
  • 따라서 변수 herDoghisDog== 연산자와 === 연산자로 비교하면, 모두 true를 반환하게 된다.


6. 객체 프로퍼티와 메서드

1) 객체 프로퍼티

  • 모든 자바스크립트 객체는 Object 객체와 Object.prototype 객체의 모든 프로퍼티를 상속받는다.
  • prototype 프로퍼티를 이용하면 현재 존재하는 프로토타입에 새로운 프로퍼티나 메서드를 손쉽게 추가할 수 있다.


2) 객체 메서드

  • 모든 자바스크립트 객체는 Object 객체와 Object.prototype 객체의 모든 프로퍼티와 메서드를 상속받는다.
  • 자주 사용되는 대표적이 객체 메서드는 다음과 같다.


1] hasOwnProperty()

2] propertyIsEnumerable()

3] isPrototypeOf()

4] isExtensible()

5] toString()

6] valueOf()


(1) hasOwnProperty() 메서드

  • hasOwnProperty() 메서드는 특정 프로퍼티가 해당 객체에 존재하는지를 검사한다.
  • 해당 객체에서 직접 선언된 프로퍼티만을 검사하며, 같은 이름의 프로퍼티라도 상속받은 프로퍼티는 false 값을 반환한다.


function Dog(color, name, age, family) {
  this.color = color;
  this.name = name;
  this.age = age;
  this.family = family;
  this.breed = function () {
    return this.color + " " + this.family;
  };
}

var myDog = new Dog("검정색", "곰", 3, "불독");

myDog.hasOwnProperty("color"); // true
myDog.hasOwnProperty("breed"); // true
myDog.hasOwnProperty("class"); // 상속받은 프로퍼티이므로, false를 반환함.


(2) propertyIsEnumerable() 메서드

  • propertyIsEnumerable() 메서드는 특정 프로퍼티가 해당 객체에 존재하고, 열거할 수 있는 프로퍼티인지를 검사한다.
  • 즉, 이 메서드는 hasOwnProperty() 메서드의 결과가 true이면서, 동시에 열거할 수 있는 프로퍼티인지를 검사한다.


function Dog(color, name, age) {
  this.color = color;
  this.name = name;
  this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

// color 프로퍼티의 enumerable 속성을 false로 설정함.
Object.defineProperty(myDog, "color", { enumerable: false });

document.write(myDog.propertyIsEnumerable("color") + "<br>"); // false
document.write(myDog.propertyIsEnumerable("name") + "<br>"); // true
document.write(myDog.propertyIsEnumerable("age")); // true


Note

  • 열거할 수 있는 프로퍼티란 내부적으로 enumerable 플래그가 true로 설정된 프로퍼티를 의미한다.
  • 이러한 프로퍼티들은 for/in 문으로 접근할 수 있게 된다.


(3) isPrototypeOf() 메서드

  • isPrototypeOf() 메서드는 특정 객체의 프로토타입 체인에 현재 객체가 존재하는지를 검사한다.


var day = new Date(); // Date 객체를 생성함.

// 객체 day의 프로토타입이 Date.prototype인지를 검사함.
document.write(Date.prototype.isPrototypeOf(day)); // true
document.write(Date.prototype.isPrototypeOf(new String())); // false


(4) isExtensible() 메서드

  • isExtensible() 메서드는 객체에 새로운 프로퍼티를 추가할 수 있는지 여부를 반환한다.


  • 자바스크립트에서 모든 객체는 기본적으로 새로운 프로퍼티를 추가할 수 있다.
  • 하지만 preventExtensions() 메서드를 사용하여 해당 객체에 새로운 프로퍼티를 추가할 수 없도록 설정할 수 있다.


var day = new Date(); // Date 객체를 생성함.

// 객체 day에 새로운 프로퍼티를 추가할 수 있는지 검사함.
document.write(Object.isExtensible(day) + "<br>"); // true

// 해당 객체에 새로운 프로퍼티를 추가할 수 없도록 설정함.
var myDay = Object.preventExtensions(day);

document.write(Object.isExtensible(day)); // false


(5) toString() 메서드

  • toString() 메서드는 이 메서드를 호출한 객체의 값을 문자열로 반환한다.


var arr = [10, "문자열", true]; // 배열
var bool = false; // 불리언
function func() {
  return 0;
} // 함수

arr.toString(); // 10,문자열,true
bool.toString(); // false
func.toString(); // 함수의 소스 코드가 전부 문자열로 반환됨.


(6) valueOf() 메서드

  • valueOf() 메서드는 특정 객체의 원시 타입의 값을 반환한다.
  • 자바스크립트에서는 원시 타입의 값이 기대되는 곳에 객체가 사용되면, 내부적으로 이 메서드를 호출하여 처리한다.
  • 만약 어떤 객체가 원시 타입의 값을 가지고 있지 않다면, 이 메서드는 객체 자신을 반환한다.


function func(n) {
  this.number = n;
}

myFunc = new func(4);

document.write(myFunc + 5); // ①: [object Object]5

func.prototype.valueOf = function () {
  // valueOf() 메소드를 정의함.
  return this.number;
};

document.write(myFunc + 5); // ②: 9


  • 위의 예제 ① 부분에서는 산술 연산을 위해 number 타입의 값을 기대하는 곳에 myFunc 객체가 사용된다.
  • 따라서 자바스크립트는 내부적으로 해당 객체의 valueOf() 메서드를 호출한다.
  • 하지만 이 객체의 valueOf() 메서드는 아직 정의되지 않았으므로, 해당 객체 자신을 반환하게 된다.
  • 따라서 산술 연산이 아닌 문자열 결합 연산이 수행된다.
  • 그 후에 예제에서는 prototype 프로퍼티를 이용하여 valueOf() 메서드를 정의한다.
  • 따라서 ② 부분에서는 내부적으로 호출된 valueOf() 메서드가 해당 객체의 number 프로퍼티 값을 반환한다.
  • 따라서 정상적으로 산술 연산이 수행된다.


3) gettersetter 메서드의 정의

  • gettersetter 메서드로 정의된 프로퍼티는 단순한 값을 지닌 데이터 프로퍼티와는 달리 접근자 프로퍼티라고 부른다.
  • getter 메서드는 특정 프로퍼티의 값을 받아오기 위한 메서드이다.
  • 자바스크립트는 객체의 프로퍼티 값에 접근할 때 getter 메서드에 아무런 인수를 전달하지 않고 호출한다.
  • setter 메서드는 특정 프로퍼티의 값을 설정하기 위한 메서드이다.
  • 자바스크립트는 객체의 프로퍼티 값을 변경할 때 setter 메서드에 대입하고자 하는 값을 인수로 전달하여 호출한다.


  • 다음 예제는 getter 메서드를 정의하는 예제이다.


var gildong = { age: 18 };

document.write(gildong.age + "<br>"); // 18

Object.defineProperty(gildong, "americanAge", {
  get: function () {
    return this.age - 1;
  },
});

document.write(gildong.americanAge); // 17


  • 위의 예제에서는 gildong 객체에 americanAge라는 프로퍼티를 추가할 때 get 키워드를 사용하여 getter 메서드를 정의하고 있다.
  • 따라서 해당 프로퍼티를 참조하려고 할 때는 내부적으로 미리 정의한 getter 메서드가 자동으로 호출될 것이다.


  • 다음 예제는 setter 메서드를 정의하는 예제이다.


var gildong = { age: 18 };

gildong.age = 20;

document.write(gildong.age + "<br>"); // 20

Object.defineProperty(gildong, "changeAge", {
  set: function (n) {
    this.age = this.age - n;
  },
});

gildong.changeAge = 5;

document.write(gildong.age); // 15


  • 위의 예제에서는 gildong 객체에 changeAge라는 프로퍼티를 추가할 때 set 키워드를 사용하여 setter 메서드를 정의하고 있다.
  • 따라서 해당 프로퍼티의 값을 변경하려고 할 때는 내부적으로 미리 정의한 setter 메서드가 자동으로 호출될 것이다.

References