- 자바스크립트는
프로토타입 기반
의 객체지향 언어임.
- 다른 객체 지향 언어와는 달리, ES5까지는
클래스
가 없고 생성자 함수와 프로토타입을 통해 객체지향 언어의 상속을 구현함.
- ES6에서 도입된
클래스
는 프로토타입 기반 객체지향 모델과 전혀 다른 문법이 아니며, 프로토타입 기반 패턴을 클래스 형태로 사용할 수 있게 해주는 문법적 설탕
이라는 의견도 있음.
- 클래스는 생성자 함수와 매우 유사하게 동작하지만,
new 연산자 필수여부, extend, super 키워드, 암묵적 엄격모드, 열거 여부 등
몇가지 차이가 존재함.
- 클래스는 단순한 문법적 설탕이 아니라, 기존 프로토타입 기반 패턴을 사용해야 할 경우 보다 간편하고 명료한 코딩을 할 수 있게 해주는
새로운 객체 생성 방식
이라고 보는 것이 합당할 것임.
📌 클래스의 정의
- 클래스는
일급 객체
로서, 함수의 반환값으로 사용할 수 있고, 변수에 할당할 수 있으며, 함수의 인자로 전달할 수 있음.
class Person {
// 생성자
constructor(name) {
// 인스턴스 생성 및 초기화
this.name = name;
}
// 프로토타입 메서드
sayHi() {
console.log(`Hi! My name is ${this.name}`);
}
// 정적 메서드
static sayHello() {
console.log('Hello!');
}
}
// 인스턴스 생성
const me = new Person('Lee');
// 인스턴스의 프로퍼티 참조
console.log(me.name); // Lee
// 프로토타입 메서드 호출
me.sayHi(); // Hi! My name is Lee
// 정적 메서드 호출
Person.sayHello(); // Hello!
📌 클래스 호이스팅
- 클래스 선언문으로 정의한 클래스는
함수 선언문과 동일하게 호이스팅
이 발생함.
- 클래스 선언문 이전에 클래스를 참조하면
참조 에러
가 발생함. 호이스팅이 발생하지 않는 것 처럼 동작하지만 실제로는 호이스팅이 발생함.
var, let, const, function, class
키워드를 사용하여 선언한 모든 식별자는 호이스팅이 발생함. 모든 선언문은 런타임 이전에 먼저 실행되기 때문임.
📌 인스턴스 생성
- 클래스는 생성자 함수와 달리
new 연산자 없이 호출
하면 에러가 발생함.
📌 메서드
- 클래스는 생성될 인스턴스의 프로퍼티를 정의하는
필드
와 메서드
로 구성됨.(ES2020 이후)
- 클래스 몸체에서 정의할 수 있는 메서드는
constructor
, 프로토타입 메서드
, 정적 메서드
가 있음.
- constructor는 클래스로 인스턴스를 생성하고 초기화하기 위한 특수한 메서드로, 이름 변경이 불가능함.
- 프로토타입 메서드는
프로토타입
에 바인딩되어 인스턴스의 프로토타입 체인
을 통해 사용할 수 있음.
- 정적 메서드는 인스턴스를 생성하지 않아도 호출할 수 있는 메서드임. 프로토타입 메서드와 달리
인스턴스의 프로토타입 체인
에 바인딩되지 않고 클래스로 호출됨.
- 클래스에서 정의한 메서드는 암묵적으로 엄격모드로 실행되고, 축약 표현을 사용해야하며, 객체 리터럴과는 다르게
콤마
로 메서드를 구분하지 않음.
- 또한
for...in
문이나 Object.keys
메서드 등으로 열거할 수 없으며, non-constructor이기 때문에 new 연산자와 함께 호출이 불가능함.
📌 클래스의 인스턴스 생성 과정
- 클래스의 인스턴스 생성 과정은 생성자 함수와 유사함.
- 먼저 new 연산자와 함께 클래스를 호출하면 암묵적으로 빈 객체(인스턴스)가 생성되고, 인스턴스의 프로토타입 체인이 생성되고, 이후 this에 인스턴스가 바인딩됨.
- constructor의 내부 코드가 실행되어 this에 바인딩된 인스턴스를 초기화하고, this에 바인딩되어 있는 인스턴스에 프로퍼티를 추가하여 인스턴스의 프로퍼티 값을 초기화함.
- 이와같은 처리가 모두 끝나면 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환됨.
📌 프로퍼티
- 인스턴스의 프로퍼티는
constructor
내부에서 정의해야함.
getter
와 setter
등의 접근자 프로퍼티는 그자체로 값을 갖지 않고, 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용됨.
- 클래스 몸체에서 프로퍼티를 정의한 부분을
클래스 필드
라고 함.
- 클래스 필드에서 정의한 프로퍼티는 외부 접근을 막는
private
접근 제한자를 통해 간접적으로 캡슐화를 구현할 수 있음.
static
키워드를 사용하여 정적 프로퍼티를 정의할 수 있음.
📌 상속에 의한 클래스 확장
- 프로토타입 기반 상속은 프로토타입 체인을 통해 다른 객체의 자산을 상속받는 개념이지만, 상속을 통해 클래스를 확장하는 것은
클래스를 상속
받아 새로운 클래스를 확장하는 것을 의미함.
- 상속을 통해 확장된 클래스는
부모 클래스
의 기능을 그대로 사용할 수 있으며, 부모 클래스
의 기능을 재정의
하거나 확장
할 수 있음.
- 상속을 통해 클래스를 확장하려면
extends
키워드를 사용하여 상속받을 클래스를 지정해야함.
super
키워드는 부모 클래스를 참조할 때 사용함.
예상질문
- 자바스크립트의 클래스에 대해 아는대로 설명해주세요.
레퍼런스