클래스의 규칙?
- 클래스를 new 연산자 없이 호출하면 에러 발생. 하지만 생성자 함수를 new 연산자 없이 호출하면 일반 함수로 호출.
- 클래스는 상속을 지원하는 extends와 super 키워드를 제공. 하지만 생성자 함수는 extends와 super 키워드를 제공하지 않음.
- 클래스는 호이스팅이 발생하지 않는 것처럼 동작. 하지만 함수 선언문으로 정의된 생성자 함수는 함수 호이스팅이, 함수 표현식으로 정의한 생성자 함수는 변수 호이스팅이 발생
- 클래스 내의 모든 코드에는 암묵적으로 strict mode가 지정되어 실행되며 strict mode를 해제할 수 없다. 하지만 생성자 함수는 암묵적으로 strict mode가 지정되지 않는다.
- 클래스의 constructor, 프로토타입 메소드, 정적 메소드는 모두 프로퍼티 어트리뷰트의 값이 false다. -> 열거되지 않는다.
클래스 정의
- 클래스 몸체에서 정의할 수 있는 메소드는 생성자, 프로토타입 메소드, 정적 메소드 3가지가 있다.
- 코드 예시
// 클래스 선언문
class Person {
// 생성자
constructor(name) {
// 인스턴스 생성 및 초기화
this.name = name; // name 프로퍼티는 public하다.
}
// 프로토타입 메소드
sayHi() {
console.log(`Hi` I'm ${name});
}
// 정적 메소드
static sayHello() {
console.log("Hello");
}
}
// 인스턴스 생성
const me = new Person("HOONEY");
// 인스턴스 프로퍼티 참조
console.log(me.name); // HOONEY
// 프로토타입 메소드 호출
me.sayHi(); // Hi I'm HOONEY
// 정적 메소드 호출
Person.sayHello(); // Hello
클래스 호이스팅
console.log(Person);
// ReferenceError
class Person {}
- 클래스 선언문은 호이스팅이 발생하지 않는 것 처럼 보인다.
conset Person = '';
{
// 호이스팅이 발생하지 않는다면 ''이 출력되어야 함.
console.log(Person); // ReferenceError
class Person {}
}
- 클래스는 let, const로 선언한 변수처럼 호이스팅이 된다.
인스턴스 생성
- 클래스는 생성자 함수이며 new 연산자와 함께 호출되어 인스턴스를 생성한다.
class Person {}
const me = new Person();
console.log(me); // Person {}
메소드
constructor
class Person {
constructor(name) {
this.name = name;
}
}
- constructor는 클래스 내에 1개만 존재 가능
- constructor는 생략 가능 - 생략 시 비어 있는 constructor가 정의
정적 메소드
- 클래스 내에서 static 키워드를 붙여 함수를 정의하면 정적 메소드가 된다.(클래스 메소드)
class Person {
static sayHi() {
console.log('Hi!');
}
}
정적 메소드와 프로토타입 메소드의 차이
- 정적 메소드와 프로토타입 메소드는 자신이 속해 있는 프로토타입 체인이 다르다.
- 정적 메소드는 클래스로 호출하고 프로토타입 메소드는 인스턴스로 호출한다.
- 정적 메소드는 인스턴스 프로퍼티를 참조할 수 없지만 프로토타입 메소드는 인스턴스 프로퍼티를 참조할 수 있다.
클래스의 인스턴스 생성 과정
- 인스턴스 생성과 this 바인딩
- 인스턴스 초기화
- 인스턴스 반환
class Person {
constructor(name) {
// 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩 된다.
console.log(this); Person {}
// 2. this에 바인딩되어 있는 인스턴스를 초기화 한다.
this.name = name;
// 3. 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환돤다.
}
}
접근제한자
- JS에서 접근제한자는 기본적으로 public이다.
class Person {
// private
#name = '';
constructor(name) {
// private 필드 참조
this.#name = name;
}
}
const me = new Person("HOONEY");
// private은 외부에서 참조 불가
console.log(me.#name); //SyntaxError
class MyMath {
static PI = 22/7;
// static private 필드 정의
static #num = 10;
// static 메소드
static increment () {
return ++MyMath.#num;
}
}
console.log(MyMath.PI); // 3.14...
console.log(MyMath.increment()); // 11
다음 포스팅에 이어서...