생성자패턴 - accidentlywoo/legacyVue GitHub Wiki
생성자패턴
- 들어가기 전에 자바스크립트로 구현한 애플리케이션도 꽤 복잡해질 수 있습니다. 함수만으로 나누기 보다는, 어떠한 집합개념으로 모듈화를 할 필요가 있습니다. 객체지향 언어에서는 클래스라고 하는 것이 그것입니다. 자바스크립트도 객체 형태로 비슷한 속성과 행위를 묶어서 표현할 수 있는데, 좀 더 객체지향적인 방법으로 이를 표현할 수가 있습니다. 생성자 패턴을 통해서 그 방법을 이해해 보겠습니다.
학습 목표
- 생성자 패턴을 이해합니다.
핵심 개념
- constructor
- prototype
학습하기
자바스크립트 객체 다시 이해하기
우리는 아래와 같은 코드를 객체리터럴(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`
생각 해보기
- prototype과 new 키워드를 사용해서 구현할 수 있는 객체지향 자바스크립트 코드가 어떤 형태인지 찾아보면 좋겠습니다. 생각보다 다양한 패턴이 존재하며 각각의 특징을 알아가면서 prototype의 특성을 알게 될 겁니다.
- __proto__라는 속성이 있습니다. 앞선 예제에서 h,h2를 이용해서 h2.__proto__와 같은 식으로 접근해서 결과를 확인해보세요. 직접 쓸 일은 없지만,내부 prototype 정보를 들여다볼 수 있습니다.
- Object.create 를 사용해서도 클래스와 같은 코드를 만들 수 있습니다.
- ES6에서는 Class라는 키워드가 존재합니다. 어떻게 클래스를 만들고 메서드를 추가할 수 있는지 예제를 찾아서 확인해보세요. 많은 framework들이 이런 패턴으로 컴포넌트를 만들고 있습니다. 그런데 ES6 Class도 결국은 prototype을 활용해서 클래스구조를 생성한답니다. 따라서 prototype에 대한 이해는 자바스크립트를 이해하는데 꼭 알아둬야 할 개념입니다.