클래스와 인스턴스를 알아보자!
먼저 객체지향 프로그래밍이란?
객체지향 프로그래밍
- OOP, Object-oriented programming
- 하나의 모델이 되는 (blueprint) 만들고, 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴이다.
청사진은 자동차 생산을 위한 설계도에 비유된다. 자동차가 기능하기 위해서는 네 바퀴와 핸들, 좌석 그리고 엔진이 필요한데, 이러한 기본적인 설계는 차의 종류에 상관없이 대체적으로 동일하게 적용된다.
이런 설계도(청사진)를 바탕으로 각각의 객체가 특정한 자동차 모델로 나오게 되는 것!
그렇다면 객체는 어떻게 만들까?
클래스를 만드는 새로운 문법이 ES6(ECMAScript 6, 비교적 최근 자바스크립트 문법)에 도입되었다!
//ES5 클래스는 함수로 정의할 수 있다.
function Car(brand, name, color){
// 인스턴스가 만들어질 때 실행되는 코드
}
//ES6에서는 class라는 키워드를 이용해서 정의할 수도 있다
class Car {
constructor (brand, name, color){
// 인스턴스가 만들어질 때 실행되는 코드
}
}
여기서 보이는 함수는, 객체지향 프로그래밍에서 생성자(constructor) 함수라고 부른다. 인스턴스가 만들어질 때 실행되는 코드이다.
참고로 생성자 함수는 return 값을 만들지 않는다.
그럼 인스턴스는 어떤 형식으로 만들어야 할까?
//new 키워드를 통해 클래스의 인스턴스를 만들어 낼 수 있다
let avante = new Car("hyundai", "avante", "black");
let mini = new Car("bmw", "mini", "white");
let beetles = new Car("volkswagen", "beetles", "red");
클래스에 속성과 메소드를 정의하고, 인스턴스에서 이용한다
//ES5
function Car(brand, name, color){
this.brand = brand;
this.name = name;
this.color = color;
}
//ES6
class Car {
constructor (brand, name, color){
this.brand = brand;
this.name = name;
this.color = color;
}
}
여기서 this라는 새로운 키워드가 등장한다. 객체지향 프로그래밍에서는 빠지지 않고 등장하니 꼭 기억하자!
//ES5
function Car(brand, name, color){/*생략*/}
car.prototype.refuel = function(){
//연료 공급을 구현하는 코드
}
car.prototype.drive = function(){
//운전을 구현하는 코드
}
//ES6
class Car {
constructor (brand, name, color){/*생략*/}
refuel() {
}
drive() {
}
}
Car.prototype.refuel
과 같이 prototype
을 이용해야 한다.refuel() {}
, drive() {}
와 같이 작성되어 있는 부분이다.let avante = new Car ("hyundai", "avante", "black");
avante.color; //black
avante.drive(); //아반떼가 운전을 시작합니다
let mini = new car ("bmw", "mini", "white");
mini.brand; //"bmw"
mini.refuel(); //미니에 연료를 공급합니다
그렇다면 이제 prototype, constructor, this를 비교해보자!
이제 실전으로 들어가서 예제를 한 번 보자!
let avante = new car ("hyundai", "avante", "black");
avante.color; //black
avante.drive(); //아반떼가 운전을 시작합니다
let arr = ["code", "states", "pre"];
arr.length; //3
arr.push("course"); //새 element를 추가합니다
배열은 (대문자) Array의 인스턴스이다.
따라서 new Array(, , ___) 와 같은 방식으로도 배열을 만들 수 있다.
살짝만 더 깊게 들어가 보면, 배열 메서드 (push, filter, forEach...) 등을 배울 때에, mdn 문서를 유심히 살펴보면, 메서드들이 대부분 Array.prototype.메서드명 과 같이 안내되어 있음을 발견했을 것이다.
이는 모든 메서드들이 클래스의 원형 객체(prototype)에 정의되어 있기 때문이다!
그럼 마지막으로 객체지향 프로그래밍(OOP)로 구현한 counter 예시를 하나 보자!
class Counter {
constructor() {
this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스입니다
}
increase() {
this.value++
}
decrease() {
this.value--
}
getValue() {
return this.value
}
}
let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1