JS LAB
JS 6.1 · 6부. 객체지향과 모던 JS

클래스와 인스턴스

class 로 형태를 정하고 객체를 만듭니다.

예상 학습 시간 15분 실행 단추가 있는 예제는 고쳐서 실행해 볼 수 있습니다 난이도 중급
개념 설명

같은 모양의 객체를 여럿 만듭니다

3.6 에서 객체를 만들었습니다. 상품이 하나면 그대로 적으면 되지만, 여럿이라면 같은 모양을 되풀이해 적게 됩니다.

클래스(class) 는 그 모양을 한 번 적어 두고 필요할 때마다 만들어 내는 방법입니다. 클래스로 만들어 낸 객체를 인스턴스(instance) 라고 합니다.

최소 예제 · 편집 가능

클래스 만들고 찍어 내기

script.js
class Product {
	constructor(name, price) {
		this.name = name;
		this.price = price;
	}

	describe() {
		return `${this.name} ${this.price}원`;
	}
}

const pencil = new Product("연필", 1000);
const note = new Product("공책", 2000);

console.log(pencil);
console.log(pencil.name);
console.log(pencil.describe());
console.log(note.describe());
출력
Product { name: "연필", price: 1000 } 연필 연필 1000원 공책 2000원
  • new 로 만듭니다.
  • constructor 는 만들 때 한 번 실행됩니다. 받은 값을 this 에 담습니다.
  • this지금 만들어지는 그 객체입니다. 6.3 에서 자세히 다룹니다.
  • 메서드는 function 없이 이름과 괄호만 적습니다.
상세 사용법

필드에 기본값 두기

constructor 없이도 값을 정해 둘 수 있습니다. 만들어질 때마다 새로 하나씩 생깁니다.

script.js
class Counter {
	count = 0;

	increase() {
		this.count++;
		return this.count;
	}
}

const a = new Counter();
const b = new Counter();

console.log(a.increase());
console.log(a.increase());
console.log(b.increase());
출력
1 2 1

2.5 의 클로저 카운터와 같은 일을 합니다. 다를 것은 여럿을 만들어 이름을 붙여 다루기 쉽다는 점입니다.

상세 사용법

감추는 필드

이름 앞에 # 을 붙이면 클래스 밖에서 읽을 수 없습니다. 2.5 에서 클로저로 하던 일을 문법으로 합니다.

script.js
class Account {
	#balance = 0;

	deposit(amount) {
		if (amount <= 0) return this.#balance;

		this.#balance += amount;
		return this.#balance;
	}

	get balance() {
		return this.#balance;
	}
}

const account = new Account();

console.log(account.deposit(1000));
console.log(account.deposit(-50));
console.log(account.balance);
console.log(account);
출력
1000 1000 1000 Account {}

마지막 줄을 보세요. 감춘 필드는 객체를 출력해도 보이지 않습니다.

get 을 붙인 메서드는 괄호 없이 속성처럼 읽습니다(account.balance). 읽기만 열어 두고 쓰기는 막을 때 사용합니다.

상세 사용법

객체 없이 부르는 것

static 을 붙이면 인스턴스가 아니라 클래스에 붙습니다. 만들어진 객체 하나하나와 상관없는 일에 사용합니다.

script.js
class Product {
	static count = 0;

	constructor(name) {
		this.name = name;
		Product.count++;
	}

	static fromText(text) {
		return new Product(text.trim());
	}
}

const a = new Product("연필");
const b = Product.fromText("  공책  ");

console.log(b.name);
console.log(Product.count);
console.log(a.count);
출력
공책 2 undefined

마지막 줄이 undefined 입니다. static 은 클래스에 붙어 있어 인스턴스에서는 보이지 않습니다.

흔한 실수

처음에 자주 걸리는 것

1. new 를 빠뜨립니다

Product("연필") 처럼 그냥 부르면 오류가 납니다.

TypeError: Class constructor Product cannot be invoked without 'new'
2. this 를 빠뜨립니다

메서드 안에서 name 만 적으면 그런 변수를 찾습니다. 그 객체의 속성은 this.name 입니다.

ReferenceError: name is not defined
3. 메서드 사이에 쉼표를 찍습니다

객체는 쉼표로 구분하지만 클래스 안은 쉼표를 찍지 않습니다.

SyntaxError: Unexpected token ','
실습 문제

직접 해보기

1. 학생 클래스 난이도 하

이름과 점수를 받는 Student 클래스를 만들고, "홍길동: 합격" 형태를 돌려주는 메서드를 두세요. 60점 이상이면 합격입니다.

class Student { constructor(name, score) { this.name = name; this.score = score; } result() { return `${this.name}: ${this.score >= 60 ? "합격" : "불합격"}`; } } console.log(new Student("홍길동", 80).result()); console.log(new Student("김철수", 50).result());
2. 장바구니 클래스 난이도 중

상품을 담고, 총액을 돌려주고, 개수를 알려 주는 장바구니를 만드세요. 담긴 목록은 밖에서 손대지 못하게 감춥니다.

배열 필드를 # 으로 감추고, 총액은 3.4 의 reduce 로 구합니다.
class Cart { #items = []; add(name, price) { this.#items.push({ name, price }); return this.#items.length; } get total() { return this.#items.reduce((sum, item) => sum + item.price, 0); } get count() { return this.#items.length; } } const cart = new Cart(); cart.add("연필", 1000); cart.add("공책", 2000); console.log(cart.count); console.log(cart.total);
요약

이 단원의 정리

  • 클래스는 같은 모양의 객체를 여럿 만드는 방법입니다.
  • new 로 만들고, constructor 가 한 번 실행됩니다.
  • 메서드 안에서 그 객체의 속성은 this.이름 입니다.
  • # 을 붙인 필드는 클래스 밖에서 읽을 수 없습니다.
  • static 은 클래스에 붙습니다. 인스턴스에서는 보이지 않습니다.