자바스크립트는 프로토타입 기반 객체지향 언어 이기 때문에 ES6이전에는 클래스가 필요 없는 객체 지향 프로그래밍 언어였다. ES6에서 클래스가 등장했고 마치 문법적 설탕 처럼 보일 수 있다. 그렇지만 프로토타입과 클래스는 유사하게 동작하지만 분명 차이점이 있기 때문에 문법적 설탕이라기 보다 새로운 객체 생성 메커니즘이라고 보는게 더 정확하다고 판단된다.
프로토타입(Prototype) | 클래스(Class) | |
---|---|---|
생성 방법 | 함수를 사용하여 생성자를 정의 | class 키워드를 사용하여 정의 |
상속 방법 | 프로토타입 체인 | extends 키워드 사용 |
상속 체인 | 상속 체인의 맨 위에는 Object.prototype이 위치 | 상속 체인의 맨 위에는 클래스 자신이 위치 |
호이스팅 | 함수선언문 => 함수 호이스팅 / 함수 표현식 => 변수 호이스팅 | 발생하지 않는 것처럼 동작(const, let 처럼) |
new 연산자 없이 에러 여부 | 일반 함수로서 호출 | 에러 발생 가능 |
strict mode | 암묵적 지정 x | 암묵적 지정 o, 해제할 수 없다. |
const Person = class {};
const Person = class MyClass {};
클래스는 함수로 평가된다. 따라서 런타임 이전에먼저 평가되어 함수 객체를 생성한다.
클래스는 const, let 처럼 일시적 사각지대에 빠지기 때문에 호이스팅이 되지만 되지 않는것처럼 보인다.
cosnt Person = '';
{
console.log(Persion)
//만약 호이스팅이 발생하지 않으면 ''이 출력되어야 한다.
//그렇지만 실제 결과는 'ReferenceError: Cannot access Persion before initialization'
class Person{}
}
클래스는 총 3가지의 매서드를 정의할 수 있다.
1. constructor(생성자)
2. 프로토타입 메서드
3. 정적 메서드
1. arguments
2. caller
3. length
4. prototype > constructor 는 자기자신을 가리키고 있다. (생성자 함수라는 것을 의미)
class Person {
constructor(name){
this.name = name;
}
getName() {
console.log(this.name);
}
//Person.prototype.getName() 처럼 할 필요가 없다
}
class Person {
static sayHi() {
console.log('Hi!');
}
}
정적 메소드 (Static Method) | 프로토타입 메서드 (Prototype Method) | |
---|---|---|
정의 방법 | 클래스에 직접 선언 | 프로토타입에 선언 |
this | this를 사용할 수 없음 | this를 사용할 수 있음 |
인스턴스에서 | 인스턴스에서 직접 호출 불가 | 인스턴스에서 호출 가능 |
클래스에서 | 클래스에서 직접 호출 가능 | 클래스에서 호출 불가 |
상속 | 상속되지 않음 | 상속됨 |
용도 | 객체를 생성하지 않는 메서드 | 객체를 생성하는 메서드 |
이 둘의 차이점은 쉽게 말해 클래스 내부의 변수에 접근하는 함수냐 아니냐에 따라 사용유무를 결정할 수 있다.