Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

25-1장 클래스 - 김다은 #1022

Merged
merged 1 commit into from
Dec 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions docs/25_클래스/김다은.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# 25장 클래스

## 1. 클래스는 프로토타입의 문법적 설탕인가?

자바스크립트는 프로토타입 기반 객체지향 언어로 클래스가 필요없다. 생성자 함수와 프로토타입을 통해 상속을 구현할 수 있기 때문이다. 한편 클래스 기반 언어에 익숙한 프로그래머들에게는 이것이 장벽이 될 수 있으므로 그들이 더 빠르게 학습할 수 있도록 ES6에서 새로운 객체 생성 매커니즘을 제시하는데, 그것이 바로 자바스크립트의 클래스이다. 따라서 자바스크립트의 클래스는 문법적 설탕이라고 볼 수도 있다.

하지만 생성자 함수와 클래스가 정확하게 동일하게 동작하지는 않는다.

1. 클래스를 new 연산자 없이 호출하면 에러가 발생한다. 생성자 함수는 new 연산자 없이 호출하면 일반 함수로서 호출된다.
2. 클래스는 extends와 super 키워드로 상속을 지원한다. 생성자 함수는 해당 키워드를 지원하지 않는다.
3. 클래스는 호이스팅이 발생하지 않는 것 처럼 동작한다. 생성자 함수는 호이스팅이 발생한다.
4. 클래스 내의 모든 코드는 암묵적으로 strict mode가 지정된다. 생성자 함수는 그렇지 않다.
5. 클래스의 constructor, 프로토타입 메서드, 정적 메서드는 모두 [[Enumerable]]이 false다.

이러한 차이점 때문에 클래스는 단순한 문법적 설탕이라기 보단 **새로운 객체 생성 매커니즘**으로 보는 것이 합당하다.

<br/>

## 2. 클래스 정의

```js
// 클래스 선언문
class Person {}

// 익명 클래스 표현식
const Person = calss {};

// 기명 클래스 표현식
const Person = class MyClass {};
```

클래스를 표현식으로 정의할 수 있다는 것은 클래스가 값으로 사용할 수 있는 일급 객체라는 것을 의미한다.

```js
class Person {
constructor(name) {
this.name = name;
}

sayHi() {
console.log(`Hi! My name is ${this.name}`);
}

static sayHello() {
console.log('Hello');
}
}
```

<br/>

## 3. 클래스 호이스팅

클래스 선언문으로 정의한 클래스는 런터임 이전에 먼저 평가되어 함수 객체를 생성한다.(평과 결과는 constructor 함수와 프로토타입 쌍이다.) 단, **클래스는 클래스 정의 이전에 참조할 수 없다**.

그렇다고 호이스팅이 발생하지 않는 건 아니다. 다만 let, const처럼 일시적 사각지대에 빠져 호이스팅이 동작하지 않는 것처럼 동작한다.

<br/>

## 4. 인스턴스 생성

```js
class Person {}

// 인스턴스 생성
const me = new Person();
```

## 5. 메서드

클래스 안에선 constructor, 프로토타입 메서드, 정적 메서드를 선언할 수 있다.

### 1. constructor

> 인스턴스를 생성하고 초기화하기 위한 특수한 메서드.

constructor의 prototype 프로퍼티가 가리키는 프로토타입 객체는 클래스 자신이다. constructor 내부에서 this는 클래스가 생성한 인스턴스를 가리키고, this를 통해 프로퍼티를 추가할 수 도 있다.

constructor는 다른 메서드와 구별되는 몇 가지 특징이 있다.

- constructor는 메서드로 해석되지 않고 클래스가 평가되어 생성한 함수 객체 코드의 일부가 된다.
- constructor는 클래스 내에 최대 한 개만 존재할 수 있다.
- constructor는 생략 가능하다. 생략할 경우 빈 constructor가 암묵적으로 정의되고, 해당 클래스는 constructor에 의해 빈 객체를 생성한다.
- constructor는 별도의 반환문을 갖지 않아야 한다. 암묵적으로 this(인스턴스)를 반환하는 로직이 무시되기 때문이다.

### 2. 프로토타입 메서드

생성자 함수에 의한 객체 생성 방식과는 다르게 prototype 프로퍼티에 추가해주지 않아도 기본적으로 프로토타입 메서드가 된다.

### 3. 정적 메서드

클래스에서는 static 키워드를 붙이면 정적 메서드가 된다. 정적 메서드는 클래스에 바인딩된 메서드로 클래스가 소유한 프로퍼티가 되어 인스턴스를 생성하지 않아도 호출할 수 있다.

### 4. 정적 메서드와 프로토타입 메서드의 차이

> 🔎 자바스크립트의 정적 메서드와 프로토타입 메서드는 몇 가지 차이가 있다.
>
> - 호출 방식: 정적 메서드는 인스턴스를 생성하지 않고 클래스 이름으로 직접 호출된다.
> - 사용 목적: 정적 메서드는 인스턴스와 독립적인 기능을 제공하거나, 해당 클래스에 고유한 기능(헬퍼 함수, 설정 함수)을 제공하는 데 사용된다. 반면 프로토타입 메서드는 인스턴스의 데이터에 접근하거나 조작하는 기능을 제공하는 데 주로 사용된다.
> - this 참조: 정적 메서드의 this는 클래스 자체를 가리킨다. 따라서 정적 메서드 내에서는 클래스의 정적 속성에 접근할 수 있다. 프로토타입 메서드는 해당 메서드를 호출한 인스턴스를 가리킨다. 따라서 인스턴스의 속성과 메서드에 접근할 수 있다.

표준 빌트인 객체인 Math, Number, JSON 등은 다양한 정적 메서드를 가지고 있다. 이들의 정적 메서드는 애플리케이션 전역에서 사용할 수 있는 유틸리티 함수로, 정적 메서드의 사용의 예시가 된다.

### 5. 클래스에서 정의한 메서드의 특징

1. function 키워드를 생략한 메서드 축약 표현을 사용한다.
2. 객체 리터럴과는 다르게 콤마가 필요 없다.
3. 암묵적으로 strict mode가 실행된다.
4. for ...in 문이나 Object.keys 메서드 등으로 열거할 수 없다.
5. 내부 메서드 [[Construct]]를 갖지 않는다. 따라서 new 연산자와 함께 호출할 수 없다.
Loading