생성자패턴
해당 Post는 생성자패턴에 대해서 정리한 파일입니다.
자바스크립트로 구현한 애플리케이션도 꽤 복잡해질 수 있습니다.
함수만으로 나누기 보다는, 어떠한 집합개념으로 모듈화를 할 필요가 있습니다.
객체지향 언어에서는 클래스라고 하는 것이 그것입니다.
자바스크립트도 객체 형태로 비슷한 속성과 행위를 묶어서 표현할 수 있는데, 좀 더 객체지향적인 방법으로 이를 표현할 수가 있습니다.
자바스크립트 객체 이해하기
아래와 같은 코드를 객체리터럴(Object literal)라고 합니다.
var healthObj = {
name : "달리기",
lastTime : "PM10:12",
showHealth : function() {
console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
}
}
healthObj.showHealth();
그런데 healthObj의 형태를 가진 여러개의 객체가 필요하다면 어떻게 할까요?
healthObj2, healthObj3…
그렇게 구현해도 되지만, 비슷한 객체를 계속 중복해서 만들어 두는 건 이상해보이죠.
더군다나 각 객체마다 showHealth라는 메서드는 중복으로 들어가 있을 겁니다.
객체를 동적으로 생성하는 방법
먼저 객체를 동적으로 생성하는 방법을 알아보겠습니다.
먼저, 아래 코드를 실행해보세요.
function Health(name, lastTime) {
this.name = name;
this.lastTime = lastTime;
this.showHealth = function(){...}
}
const h = new Health("달리기", "10:12");
h는 객체입니다.
h안을 들여다보면 어떻게 구성되어 있는지 알 수 있습니다.
Health함수를 한 번 더 불러서 h2객체를 만듭니다.
h2 = new Health("걷기", "20:11");
계속 이런식으로 객체를 만들어낼 수 있습니다.
Health함수는 new키워드로 불리면서, 객체를 생성하는 함수 역할을 합니다.
그래서 Health를 생성자(constructor)라고 합니다.
하지만 아직 문제가 하나 존재합니다.
아직 h와 h2를 열어보면 showHealth메서드가 여전히 중복해서 존재합니다.
이처럼 동일한 메서드가 여기저기 메모리 공간을 차지하는 것은 분명 자원 낭비입니다.
prototype으로 메서드를 같이 사용해보자
자바스크립트는 prototype이라는 공간을 통해서 객체간의 재사용 되는 것을 바라보게 할 수 있습니다.
개념적으로는 이렇습니다.
그림 - 프로토 타입 그림
prototype
그림을 보았을 때 ‘이것이 상속(inheritance)인가?’싶습니다.
실제로 비슷한 개념이라 할 수도 있습니다.
위 그림에서는 각 인스턴스(h, h2, h3)가 prototype이라는 같은 참조객체를 바라보고 있는 것입니다.
따라서 prototype의 어떤 속성을 변경하면 모든 인스턴스에게 공유됩니다.
prototype에 어떠한 속성을 추가하면서 실제 코드로 확인해보겠습니다.
아래 코드를 보면 Health 함수 아래 prototype 객체가 존재하고, 이것에 showHealth 메서드를 속성으로 추가했습니다.
이런 식으로 prototype객체 안에 여러 가지 속성을 추가할 수 있습니다.
function Health(name, lastTime) {
this.name = name;
this.lastTime = lastTime;
}
Health.prototype.showHealth = function() {
console.log(this.name + "," + this.lastTime);
}
const h = new Health("달리기", "10:12");
console.log(h);
h.showHealth();
그럼 아래처럼 여러 인스턴스를 만들어도 prototype안의 showHealth는 같은 참조점을 바라보고 있는 것을 알 수 있습니다.
const h = new Health("달리기", "10:12");
const h2 = new Health("걷기", "14:20");
console.log(h.showHealth === h2.showHealth); //true