자바스크립트는 프로토타입을 기반으로 객체지향 프로그래밍을 지원한다. 객체지향 프로그래밍이란 절차적으로 코드를 작성하지 않고 '클래스'라는 데이터 모델의 청사진을 사용해 코드를 작성하는 것을 말한다.
class Student {
// constuctor: new 키워드로 객체를 생성할 때 호출되는 함수
constructor (name, grade) {
this.name = name;
this.grade = grade;
}
// 함수는 대개 생성자 밖에서 정의한다
display = () => {
console.log(`${this.name}`);
}
}
// kim은 Student 클래스의 인스턴스이다
const kim = new Student('kim', 'A');
console.log(kim.name); // kim
위의 Student 클래스를 통해 만들어진 인스턴스는 display라는 메서드를 가진다. 이 display 메서드는 만들어진 인스턴스에게 각각 부여되는 인스턴스 레벨의 메서드이다.
각각의 인스턴스가 가진 값을 출력하는 display와 다르게, 모든 객체가 동일하게 참조해야 하는 특성이나 행동이 있을 수 있다. 이렇게 개별 인스턴스의 데이터를 참조하지 않아도 되는 경우 static 키워드를 사용하여 클래스 레벨의 메서드나 프로퍼티를 만든다.
// 인스턴스 레벨에서 정의하는 것보다 재사용성이 높아졌다
static displayManager {
console.log("이 자료는 황00 담임교사가 제작했습니다");
}
ES5에서는 ES6와 다른 형태를 가지고 있다.
class Student {
this.name = name;
this.grade = grade;
// prototype 표기
Student.prototype.display = function () {
console.log(`${this.name}`);
}
}
캡슐화는 은닉(내부 데이터나 구현을 외부에서 수정할 수 없도록 숨겨두는 것)이라는 특성을 내포하고 있다.
클래스에서는 이를 구현하기 위해 #을 이용한다.
아래에서 #을 사용하여 프로퍼티나 메서드를 정의하는 경우, <클래스의 구성> 예제와 달리 외부에서 데이터를 조회하지 못하는 것을 확인할 수 있다.
class Student {
#name;
#grade;
constructor (name, grade) {
this.#name = name;
this.#grade = grade;
}
}
const kim = new Student('kim', 'A');
console.log(kim.name); // undefined
절차적으로 코드를 작성하는 경우 데이터의 형태가 바뀌면 코드의 흐름에도 영향을 주어 유지보수가 어려워질 수 있다. 객체 지향 프로그래밍에서는 은닉화의 특징을 살려 이러한 단점을 방지할 수 있다.
예를 들어, 구현된 메서드에 수정이 필요한 경우 객체 내 메서드만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 작성할 수 있다.
세터와 게터는 이러한 맥락을 따라 설정하는 함수와 불러오는 함수를 더 엄격하게 구분한 것이다. 사용 여부는 아래 조건에 따라 결정할 수 있다.
1. 사용 시점에 변수를 참조하도록 해야 할 때
2. 함수의 내용이 행위보다는 단순한 객체 상태를 조회하는 것에 가까울 때