
참고자료
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Classes/constructor
https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Classes/Private_class_fields
https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Classes/Public_class_fields
ES6 클래스 문법은 좀더 JAVA스럽게 객체 지향적으로 표현하기 위해 추가된 새로운 문법이다.
ES5까지 자바스크립트에는 클래스가 없었다. 그래서 프로토타입 체이닝을 통해 클래스 비스무리하게 구현해왔었는데 ES6 버젼에 들어서면서 클래스와 비슷한 구조 문법을 추가하였다.
다만 생김새만 클래스 구조이지, 엔진 내부적으로는 프로토타입 방식으로 작동된다.
다음은 프로토타입 문법과 클래스 문법의 간단한 차이이다.
이 둘은 같은 결과를 출력하지만, 문법 생김새만 다르고 내부 로직은 완전히 같은 구조라는 점만 기억하면 된다.
ES5 클래스 문법
// 생성자
function Person({name, age}) {
this.name = name;
this.age = age;
}
Person.prototype.introduce = function() {
return `안녕하세요, 제 이름은 ${this.name}입니다.`;
};
const person = new Person({name: '윤아준', age: 19});
console.log(person.introduce()); // 안녕하세요, 제 이름은 윤아준입니다.
ES6 클래스 문법
// 클래스
class Person {
// 이전에서 사용하던 생성자 함수는 클래스 안에 `constructor`라는 이름으로 정의합니다.
constructor({name, age}) { //생성자
this.name = name;
this.age = age;
}
// 객체에서 메소드를 정의할 때 사용하던 문법을 그대로 사용하면, 메소드가 자동으로 `Person.prototype`에 저장됩니다.
introduce() {
return `안녕하세요, 제 이름은 ${this.name}입니다.`;
}
}
const person = new Person({name: '윤아준', age: 19});
console.log(person.introduce()); // 안녕하세요, 제 이름은 윤아준입니다.
생성자 함수인, constructor는 인스턴스를 생성하고 클래스 필드를 초기화하기 위한 특수한 메서드이다.
constructor는 클래스 안에 한 개만 존재할 수 있다. 2개 이상 있을 경우 Syntax Error가 발생하니까 주의하자.
class Person {
height = 180; // 인스턴스 변수
// constructor는 이름을 바꿀 수 없다.
constructor(name, age) {
// this는 클래스가 생성할 인스턴스를 가리킨다.
this.name = name;
this.age = age;
}
}
let person1 = new Person('john', 23);
console.log(person1.name); // john
console.log(person1.age); // 23
console.log(person1.height); // 180
클래스 필드의 선언과 초기화는 반드시 constructor 내부에서 실시한다.
constructor 내부에 선언한 클래스 필드는 클래스가 생성할 인스턴스에 바인딩 된다.
클래스 필드는 그 인스턴스의 프로퍼티가 되며, 인스턴스를 통해 클래스 외부에서 언제나 참조할 수 있다. (public)
this는 클래스가 생성할 인스턴스를 가리킨다.
static fields와 instance의 public fields 는 둘 다 writable, enumerable, configurable 한 프로퍼티들이다.
Public static fields 는 클래스에서 생성하는 모든 인스턴스에 대한 필드가 아닌, 클래스마다 단 한개의 필드가 존재하기를 원할 때 유용하게 사용할 수 있다. Public fields는 캐시, 고정된 설정값, 또는 인스턴스 간 복제할 필요가 없는 어떤 데이터 등에 유용하게 쓰일 수 있다.
class ParentClass {
static baseField = 'base field' ✔
}
class ChildClass extends ParentClass {
static subField = 'sub class field'
}
console.log(ChildClass.subField)
// expected output: "sub class field"
console.log(ChildClass.baseField) ✔ 자식 클래스에서 부모 클래스의 baseField 접근 가능!
// expected output: "base field"
Private static 필드는 해당 필드를 선언한 class 에서만 접근할 수 있다.
자바스크립트의 프라이빗 필드는 외부에서 클래스로 접근이 불가능하고 인스턴스로도 접근이 불가능합니다.
class Rabbit {
private static age = 0
}
console.log(Rabbit.age) ❌
// expected output: roperty 'age' does not exist on type 'typeof Rabbit'
class Rabbit {
private static age = 0;
constructor() {
Rabbit.age = 1; ⭕
}
run() {
console.log(Rabbit.age); ⭕
}
}
console.log(Rabbit.age); ❌
// Property 'age' is private and only accessible within class 'Rabbit'