JavaScript-클래스 사용하기(팩토리, 생성자)

hannah·2023년 8월 3일
0

JavaScript

목록 보기
56/121

클래스(class)

객체를 생성하기 위한 템플릿(서식)

클래스는 2015년에 자바스크립트에 추가된 문법으로, 이전에는 아래의 코드와 같이 함수로 객체를 만들었다.

function createMonster(name, hp, att, xp) {
	return	{name, hp, att, xp};
}
const monster1 = createMonster('슬라임', 25, 10, 11);
const monster2 = createMonster('슬라임', 26, 10, 10);
const monster3 = createMonster('슬라임', 25, 11, 10);

가장 간단하게 객체를 return 하는 함수를 만들어 객체를 생성한다. 이와 같이 객체를 반환하는 함수를 공장(factory)함수라고 한다. 공장처럼 객체를 찍어낸다고 해서 붙은 이름이다. createMonster를 세 번 호출했으니 슬라임 세 마리를 생성한 것이나 다름없다. 각각의 체력, 공격력, 경험치가 조금씩 다르다. 이렇게 달라지는 부분은 함수의 인수로 넘기면 된다.

여기서 중요한 점은 생성한 세 개의 객체가 서로 참조 관계가 아닌 다른 객체여야 한다는 점이다. 같은 객체를 반환하면 하나의 몬스터를 잡을 때 다른 두 마리도 같이 죽게 된다. 따라서 매번 새로운 객체를 반환하게 객체 리터럴로 작성했다.(또는 기존 객체를 깊은 복사해도 된다.)

다른 방식으로 객체를 생성해보자.

function Monster(name, hp, att, xp) {	//생성자 함수는 보통 대문자로 쓴다.
	this.name = name;
  	this.hp = hp;
  	this.att = att;
  	this.xp = xp;
}
const monster1 = new Monster('슬라임', 25, 10, 11);	
const monster2 = new Monster('슬라임', 26, 10, 10);
//new를 넣지 않으면 this가 Monster가 아닌 window를 가리키게 된다.

객체의 속성을 this에 대입하고, 함수를 호출할 때는 함수 이름 앞에 new를 붙여 호출한다. new를 붙여 호줄하는 경우에도 this는 객체 자신을 가리킨다. 이렇게 Monster에 new를 붙여 호줄하는 함수를 생성자 함수라고 한다. 실수로 new를 붙이지 않고 호출하면 this가 window가 되어 window.name의 값을 바꾸게 되니 반드시 new를 붙여 호출해야 한다.

생성자(constructor) 함수

함수 생성자는 여러 프로그래밍 언어에서는 '클래스'와 동의어다. 어떤 경우 사람들은 참조 타입(Reference Types), 클래스(Classes), 데이터 타입, 아니면 간단하게 생성자라고 부른다. 클래스에 아직 익숙하지 않다면, 어떤 속성(properties)과 행동(functions)을 정의하도록 해주고, 그 속성과 행동을 통해 여러 객체가 생성될 수 있도록 해주는 생성자라고 이해하면 된다.

생성자 함수는 이름을 지을 때 보통 대문자로 시작한다. 필수는 아니지만, 자바스크립트 개발자들이 많이 사용하는 규칙이다. new Date의 Date 함수도 생성자 함수이다.

자바스크립트는 생성자 함수를 조금 더 편하게 쓸 수 있도록 클래스 문법을 도입했다.

class Monster {
	constructor(name, hp, att, xp){
    	this.name=name;
        this.hp=hp;
        this.att=att;
        this.xp=xp;
    }
}
const monster1 = new Monster('슬라임', 25, 10, 11);
const monster2 = new Monster('슬라임', 26, 10, 10);

클래스는 객체를 생성하는 템플릿 문법이다. class 예약어클래스를 선언하고, constructor 메서드 안에 기존 코드를 넣으면 된다. 클래스에 new를 붙여 호출하면 constructor 함수가 실행되고 객체가 반환된다. 여기서 this는 생성된 객체 자신을 가리키게 된다.

클래스 문법의 장점은 객체의 메서드들을 같이 묶을 수 있다는 것이다.


class Monster {
	constructor(name, hp, att, xp){
    	this.name=name;
        this.hp=hp;
        this.att=att;
        this.xp=xp;
    }
  	attack(monster){
    	monster.hp -= this.att;
      	this.hp -= monster.att;
    }
  	heal(monster){
    	this.hp +=20;
      	this.hp -=monster.att;
    }
}

그럼 공장 함수나 생성자 함수를 사용할 때와 비교해보자.

function Monster(name, hp, att, xp) {
  return{
    	name, hp, att, xp,
		attack(monster) {
    	    monster.hp -= this.att;
      		this.hp -= monster.att;
        },
    	 heal(monster){
    		this.hp +=20;
   		   	this.hp -=monster.att;
      	},
  };
  //공장 함수

공장 함수 방식에 메서드를 추가했다. 클래스 문법과 똑같아 보이지만, 한 가지 큰 차이점은 공장 함수에서 객체를 생성할 때마다 attack과 heal 메서드도 같이 새로 생성된다. 클래스 문법에서는 한 번 만든 attack과 heal 메서드를 계속 재사용한다. 재사용해도 되는 메서드를 새로 만들어내니 매우 비효율적이다.

이번에는 생성자 함수 방식에 메서드를 추가해보자.

function Monster(name, hp, att, xp) {
	this.name = name;
  	this.hp = hp;
  	this.att = att;
  	this.xp = xp;
}
Monster.prototype.attack = runction(monster) {
	monster.hp -= this.att;
  	this.hp -= monster.att;
};
Monster.prototype.heal = runction(monster) {
	this.hp +=20;
   	this.hp -=monster.att;
};

이번에는 prototype이라는 새로운 속성이 등장했다. 생성자 함수에 메서드를 추가할 때는 prototype이라는 속성 안에 추가해야 한다. prototype 속성 안에 추가한 메서드를 프로토타입 메서드라고 한다. 이렇게 하면 공장 함수와는 달리 attack과 heal 메서드를 재사용한다. 다만, 생성자 함수와 프로토타입 메서드가 하나로 묶여 있지 않다.

이런 문제점을 모두 해결한 것이 클래스 문법이다. 생성자 함수와 메서드가 묶여 있어 보기도 편하고, 메서드 함수를 매번 재생성하는 문제도 발생하지 않는다.

문제
사람(Human) 클래스를 만들고, 생성자 메서드에서는 이름과 나이를 속성으로 입력받아라. 또한 자신의 이름과 나이를 콘솔에 출력하는 메서드도 두 개 만들어라.












정답

class Human {
	constructor(name, age){
    	this.name=name,
        this.age=age,
    }
   sayName(){
   	console.log(this.name);
   }
   sayAge(){
   	console.log(this.age);
   }
}

속성은 constructor 안에 선언하고, 메서드는 constructor 아래에 선언하면 된다. 이름(name), 나이(age) 속성과 이름 출력(sayName), 나이 출력(sayAge) 메서드를 선언한 모습이다.

0개의 댓글