객체 지향 프로그래밍은 대표적인 모델이 되는 청사진을 하나 만들고, 그 청사진을 토대로 객체를 만드는 것을 프로그래밍 패턴을 의미한다. 여기서 청사진이 되는 객체를 class, 그 청사진을 토대로 만든 객체를 instance라고 부른다. 하지만 우리는 이미 객체를 생성하는 방법을 알고 있다. 기존의 방식이 있는데 왜 새로운 방식으로 객체를 생성해야 할까?
const rectangular1 = {
length : 8;
width : 2;
getRecArea() {
return this.length * this.width
}
};
const rectangular2 = {
length : 5;
width : 7;
getRecArea() {
return this.length * this.width
}
};
객체 리터럴에 의한 객체 생성은 직관적이고 간편하다. 위의 코드를 보았을 때, rectangular1에는 해당 객체가 할당되었다는 것과 객체의 프로퍼티들을 쉽게 알 수 있다. 하지만, 동일한 프로퍼티구조를 가지는 객체를 여러개 생성해야 할 경우 매번 새롭게 선언하고 할당해야 한다. 그때그때 새로 선언하고 할당하는 것은 감당하기 힘들어진다. 지금이야 2개였지만, 10개라면? 50개라면? 100개라면?
하나의 청사진을 만들고, 이를 new 연산자와 함께 템플릿 처럼 이용해 프로퍼티 구조가 동일한 객체를 여러개 생성할 수 있다. 아래는 ES5의 문법을 적용해 클래스를 함수로 정의한 것이다.
function Rectangular (length, width) {
this.length = length;
this.width = width;
this.getRecArea =function() {
return this.length * this.width
};
}
const rectangular1 = new Rectangular(8,2);
console.log(rectangular1.getRecArea()) ; // 16
위를 ES6의 문법으로 다시 작성해보면
class Rectangular {
constructor (length, width) {
this.length = length ;
this.width = width;
}
getRecArea () {
return this.length * this.width
}
} //※constructor 는 클래스의 인스턴스 객체를 생성하고 초기화하는 메서드이다.
const rectangular1 = new rectangular(8,2);
Rectangular.protptype.output = function() { console.log('안녕하세요')};
// 위와 같은 방식으로 클래스에 속성 혹은 메서드를 정의할 수 있다.
여기서 this는 객체 스스로의 프로퍼티 혹은 메서드를 참조하기 위한 자기참조변수이다. this는 함수의 호출 방식에 따라 다르게 결정된다.
- 일반 함수로서 호출 = 전역 객체
- 메서드로서 호출 = 메서드를 호출한 객체
- 생성자 함수로서 호출 = 생성자 함수가 호출할 인스턴스
위에서 this 는 rectangular1이 된다.
생성자 함수는 말 그대로 객체(인스턴스)를 생성하는 함수다. 일반 함수와 동일한 방법으로 생성자 함수를 정의하고, new연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다. 다시말해, new연산자가 없다면? 그냥 일반적인 함수로 동작한다.(단, class키워드를 통해 정의된 클래스는 일반 함수로 할당할 수도 없다.)
사실 우리가 이미 친숙하게 알고 있던 배열 생성 방식 역시 인스턴스를 만드는 방식이다.
let test = [1, 2, 3, 4,]
는 사실
let test = new Array (1, 2, 3, 4)