Will find a way

[JS] Class 작동원리 본문

Language/Javascript

[JS] Class 작동원리

Jaka_Park 2024. 11. 15. 13:06

출처 : https://www.yes24.com/Product/Goods/92742567

 

모던 자바스크립트 Deep Dive - 예스24

『모던 자바스크립트 Deep Dive』에서는 자바스크립트를 둘러싼 기본 개념을 정확하고 구체적으로 설명하고, 자바스크립트 코드의 동작 원리를 집요하게 파헤친다. 따라서 여러분이 작성한 코드

www.yes24.com

 

Class 란 무엇인가?

- 프로토타입객체를 생성하기 위한 템플릿

- ES6 생긴 문법 (ES6 이전에도 생성자 함수로 프로토타입 객체를 생성할 수 있었음)

- 새로운 객체를 생성하는 메커니즘

- 읽는 사람 or 작성하는 사람이 편하게 디자인 된 문법(문법적 설탕)으로 직관적인 특징을 지님

객체지향
프로그램을 객체들로 구성하고 서로 상호작용을 통해 구현하는 방법 (방법론)

프로토타입
코드를 그들의 클래스들에 의존시키지 않고 기존 객체들을 복사할 수 있도록 하는 생성 디자인 패턴
프로토타입을 통해 객체지향 언어의 상속을 구현

프로토타입 기반 언어
모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체를 가진다

 

Class의 특징

- new 연산자가 있어야 호출이 가능

- 상속을 지원하는 extends와 super 키워드를 제공 (상속 관계 구현을 간결하고 명료하게함)

- 생성자 함수 기반의 객체 생성방식보다 견고하고 명료

 

Class는 어떤 타입일까?

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

console.log(typeof Person); // function

클래스 선언문으로 정의한 클래스는 함수 선언문과 같이 소스코드 평과 과정, 즉 런타임 이전에 먼저 평가되어 함수 객체를 생성한다. 이 때 클래스가 평가되어 생성된 함수 객체는 생성자 함수로서 호출할 수 있는, 즉 constructor다. 생성자 함수로서 호출할 수 있는 함수는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성된다. 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재하기 때문이다.

 

Class 클래스는 클래스 정의 이전에 참조가 불가능

console.log(Person);
// 참조 에러 ReferenceError : Cannot access 'Person' before initiailization

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

 

Class의 메서드의 종류

- Class 에 정의할 수 있는 메서드 3개

1. constructor (생성자)

2. 프로토타입 메서드

3. 정적 메서드

 

1. constructor (생성자)

> constructor는 인스턴스를 생성하고 초기화 하기 위한 특수한 메소드

class Person {
  // 생성자
  constructor(name){
    // 인스턴스 생성 및 초기화
    this.name = name;
  }
}

// class는 인스턴스를 생성하기 위한 생성자 함수
console.log(typeof Person); // function
console.dir(Person);

// 모든 함수 객체가 가지고 있는 prototype 프로퍼티가 가리키는 프로토타입 객체의
// constructor 프로퍼티는 클래스 자기 자신을 가리킴.
// 클래스가 인스턴스를 생성하는 생성자 함수를 의미

 

2. 프로토타입 메서드

> 생성자 함수를 사용하여 인스턴스를 생성하는 경우 프로토타입 메서드를 생성하기 위해서는 다음과 같이 명시적으로 프토타입 메서드를 추가해야한다.

class Person {
  // 생성자
  consturctor(name) {
  	// 인스턴스 생성 및 초기화
    this.name = name;
  }
  
  // 프로토타입 메서드
  sayHello(){
  	console.log(`Hello! My name is ${this.name}`);
  }
}

const me = new Person('Jaka');
me.sayHello(); // Hello! My name is Jaka

 

3. 정적 메서드

> 정적 메서드는 인스턴스를 생성하지 않아도 호출할 수 있는 메서드를 의미.

class Person {
  // 생성자
  constructor(name){
    this.name = name;
  }
  
  // 정적 메서드 : class에서는 앞에 static을 붙여야함
  static sayHello() {
    console.log('Hello');
  }
}

Person.sayHello(); // Hello
// 인스턴스를 생성하면 TypeError가 뜬다.

 

 

클래스 인스턴스 생성과정

1. 인스턴스 생성과 this 바인딩

- new 연산자와 함께 클래스를 호출하면 constructor의 내부 코드가 실행되기 전 암묵적으로 빈객체가 생성

 (빈 객체는 미완성된 클래스가 생성한 인스턴스)

- 이때 클래스가 생성한 인스턴스의 프로토타입으로 클래스의 프로토타입 프로퍼티가 가리키는 객체가 설정

- 그리고 암묵적으로 생성된 비 객체, 즉 인스턴스는 this에 바인딩 됨

- 따라서 constructor 내부의 this는 클래스가 생성한 인스턴스를 가리킴

 

2. 인스턴스 초기화

- constructor의 내부 코드가 실행되어 this에 바인딩 되어 있는 인스턴스를 초기화.

(this 바인딩 되어 있는 인스턴스를 추가하고 constructor가 인수로 전달받은 초기값으로 인스턴스의 프로퍼티값을 초기화.)

 

3. 인스턴스의 반환

- 클래스의 모든 처리가 끝나며 완성된 인스턴스가 바인딩된 

class Person {
  // 생성자
  constructor(name) {
  	// 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩
    console.log(this); // Person {}
    
    // 2. this에 바인딩되어 있는 인스턴스를 초기화
    this.name = name;
    
  	// 3. 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환
  }
}