😎
Onemorebottlee's TIL
  • 🤓Introduce
  • 📖DevLog
    • 💣Error
      • npm ERR! Cannot read properties of null (reading 'edgesOut')
      • git
        • src refspec main does not match any
      • NextJS
        • No img element
        • ReferenceError : document is not defined
        • `next/image` Un-configured Host
  • 📺Lecture
    • Nomad Coders
      • 초보자를 위한 리덕스 101
        • #0 Introduction
        • #1 PURE REDUX: COUNTER
        • #2 PURE REDUX: TO DO LIST
        • #3 REACT REDUX
        • #4 Redux Toolkit
      • 바닐라 JS로 그림 앱 만들기
      • React JS 마스터 클래스
        • #2 Styled Componnents
        • #3 TypeScript
        • #4 Crypto Tracker
        • #5 State Management
        • #6 Trello
        • #7 ANIMATIONS
      • Next.js 시작하기
        • #0 INTRODUCTION
        • #1 FRAMEWORK OVERVIEW
        • #2 PRACTICE PROJECT
      • Typescript로 블록체인 만들기
        • #1 Introduction
        • #2 Overview of TypeScript
        • #3 Functions
        • #4 Classes and Interfaces
        • #5 TypeScript Blockchain
      • SQL Master Class
        • #1 Introduction
        • #2 SQLite
        • #3 Data Definition Language
        • #4 Data Manipulation Language
        • #5 Subqueries and CTEs
        • #6 Indexes
        • #7 MySQL
        • #8 Foreign Keys
        • #9 JOINS
        • #10 Nomalization
        • #11 Events & Triggers
        • #12 Full-Text Indexes
        • #13 PostgreSQL
        • #14 Functions And Procedures
        • #15 Transactions
        • #16 Data Control Language
        • #17 PostgreSQL JSON Columns
        • #18 PostgreSQL Extensions
        • #19 MongoDB
        • #20 REDIS
        • #21 Javascript and Python Drivers
    • Udemy
      • TypeScript 마스터 with Webpack & React
        • [S1] 소개
        • [S2] 설치 및 설정
        • [S3] 타입 애너테이션 기초
        • [S4] 함수
        • [S5] 객체 타입
        • [S6] 배열 타입
        • [S7] 유니온타입
        • [S8] Tuple & Enum
        • [S9] 인터페이스
        • [S10] TypeScript 컴파일러
        • [S11] 미니 프로젝트 DOM, 타입 단언, 그리고 더 많은 내용
        • [S12] Class
        • [S13] TS Class
        • [S14] Generics ⭐⭐⭐⭐⭐
        • [S15] Narrowing
        • [S16] Type Declarations
        • [S17] Module
        • [S18] Webpack 과 TypeScript
        • [S19] React
    • 모두를 위한 컴퓨터 과학 CS50
      • 1. 컴퓨팅 사고
      • 2. C언어
      • 3. 배열
      • 4. 알고리즘
      • 5. 메모리
      • 6. 자료구조
    • 생활코딩
      • DATABASE
        • DATABASE1
  • 📚Book
    • 모던 자바스크립트 Deep Dive
      • 1장 프로그래밍
      • 2장 자바스크립트란?
      • 3장 자바스크립트 개발 환경과 실행 방법
      • 4장 변수
      • 5장 표현식과 문
      • 6장 데이터 타입
      • 7장 연산자
      • 8장 제어문
      • 9장 타입 변환과 단축 평가 ⭐⭐⭐
      • 10장 객체 리터럴
      • 11장 원시 값과 객체의 비교
      • 12장 함수 ⭐⭐⭐⭐
      • 13장 스코프
      • 14장 전역 변수의 문제점
      • 15장 let, const 키워드와 블록 레벨 스코프 ⭐⭐⭐
      • 16장 프로퍼티 어트리뷰트
      • 17장 생성자 함수에 의한 객체 생성
      • 18장 함수와 일급 객체 ⭐⭐
      • 19장 프로토타입 ⭐⭐⭐⭐⭐
      • 20장 strict mode
      • 21장 빌트인 객체 ⭐
      • 22장 this ⭐⭐⭐
      • 23장 실행 컨텍스트 ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
      • 24장 클로저 ⭐⭐⭐⭐⭐⭐⭐
      • 25장 클래스
      • 26장 ES6 함수의 추가 기능
      • 27장 배열 ⭐⭐⭐
      • 28장 Number
      • 29장 Math
      • 30장 Date
      • 31장 RegExp
      • 32장 String
      • 33장 7번째 데이터 타입 Symbol
      • 34장 이터러블
      • 35장 스프레드 문법
      • 36장 디스트럭처링 할당
      • 37장 Set과 Map
      • 38장 브라우저의 렌더링 과정⭐⭐⭐⭐⭐⭐⭐⭐
      • 39장 DOM ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
      • 40장 이벤트⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
      • 41장 타이머
      • 42장 비동기 프로그래밍 ⭐⭐⭐⭐⭐⭐⭐⭐
      • 43장 Ajax
      • 44장 REST API
      • 45장 프로미스
      • 46장 제너레이터와 async/await
      • 47장 에러 처리
      • 48장 모듈
      • 49장 Babel과 Webpack을 이용한 ES6+/ES.NEXT 개발 환경 구축
    • 러닝 타입스크립트
      • Ch.1 자바스크립트에서 타입스크립트로
      • Ch.2 타입 시스템
      • Ch.3 유니언과 리터럴
      • Ch.4 객체
      • Ch.5 함수
      • Ch.6 배열
      • Ch.7 인터페이스
      • Ch.8 클래스
      • Ch.9 타입 제한자
      • Ch.10 제네릭
      • Ch.11 선언 파일
      • Ch.12 IDE 기능 사용
      • Ch.13 구성 옵션
      • Ch.14 구문 확장
      • Ch.15 타입 운영
      • 용어 사전
    • 자바스크립트 완벽 가이드
    • SQL in 10 Minutes
      • 1장 SQL 이해하기
      • 2장 데이터 가져오기
      • 3장 가져온 데이터 정렬하기
      • 4장 데이터 필터링
      • 5장 고급 데이터 필터링
      • 6장 와일드카드 문자를 이용한 필터링
      • 7장 계산 필드 생성하기
      • 8장 데이터 조작 함수 사용하기
      • 9장 데이터 요약
      • 10장 데이터 그룹핑
      • 11장 서브쿼리 사용하기
      • 12장 테이블 조인
      • 13장 고급 테이블 조인 생성하기
      • 14장 쿼리 결합하기
      • 15장 데이터 삽입하기
      • 16장 데이터 업데이트와 삭제
      • 17장 테이블 생성과 조작
      • 18장 뷰 사용하기
      • 19장 저장 프로시저 사용하기
      • 20장 트랜잭션 처리 관리하기
      • 21장 커서 사용하기
      • 22장 고급 데이터 조작 옵션
    • 면접을 위한 CS 전공지식 노트
      • 4 데이터베이스
        • 4.1 데이터베이스의 기본
    • 2023 이기적 SQL 개발자 이론서 + 기출문제
      • 데이터 모델링 이해
        • S1. 데이터 모델링
  • 💻Study
    • CS 지식 발표
      • 1회차
      • 2회차
      • 3회차
      • 4회차
      • 5회차
      • 6회차
      • 7회차
      • 8회차
      • 9회차
    • TypeScript Exercises
      • Ex 1
      • Ex 2
      • Ex 3
      • Ex 4
      • Ex 5
      • Ex 6
      • Ex 7
      • Ex 8
      • Ex 9
      • Ex 10
  • 🔄ETC
    • Article
      • Atomic Design Pattern
      • 프론트엔드 개발자
    • DATABASE
      • Oracle
        • CEIL() & FLOOR() - 소수점 올림 & 내림
        • DUAL 테이블 - 임시 테이블로 결과 확인하기
    • Ubuntu
      • 어플리케이션 업데이트
Powered by GitBook
On this page
  • 25.1 클래스는 프로토타입의 문법적 설탕인가?
  • 25.2 클래스 정의
  • 25.3 클래스 호이스팅
  • 25.4 인스턴스 생성
  • 25.5 메서드
  • 25.6 클래스의 인스턴스 생성 과정
  • 25.7 프로퍼티
  • 25.8 상속에 의한 클래스 확장

Was this helpful?

  1. Book
  2. 모던 자바스크립트 Deep Dive

25장 클래스

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

JS는 프로토타입 기반 객체지향 언어다.

ES5에서는 클래스 없이 생성자 함수와 프로토타입으로 상속을 구현했다. 하지만 클래스 기반 언어에 익숙한 프로그래머들에겐 프로토타입 기반 프로그래밍이 JS의 진입 장벽이 되었다.

ES6에서 도입된 클래스는 클래스 기반 객체지향 프로그래밍 언어와 매우 흡사한 객체 생성 매커니즘을 제시했다. 하지만 이 클래스는 함수이며 기존 프로토타입 기반 패턴을 클래스 기반 패턴처럼 사용할 수 있는 문법적 설탕이라 볼 수 있다.

클래스는 생성자 함수와 매우 유사하게 동작하지만 몇 가지 차이가 있다.

  1. class는 new 연산자 없이 호출하면 에러가 발생한다.

  2. class는 상속을 지원하는 extends와 super 키워드를 제공한다.

  3. class는 호이스팅이 발생하지 않는 것처럼 동작한다.

  4. class 내 모든 코드에는 암묵적으로 strict mode가 지정되어 실행되며 해제할 수 없다.

  5. class의 constructor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 false다. 즉 열거되지 않는다.

생성자 함수와 클래스는 프로토타입 기반의 객체지향을 구현했다는 점에서 매우 유사하다. 하지만 클래스는 더 견고하고 명료하다. 특히, extends와 super 키워드는 상속 관계 구현을 더욱 간결하고 명료하게 한다.

따라서 클래스가 문법적 설탕이라 보기보다 새로운 객체 생성 매커니즘으로 보는게 합당하다.


25.2 클래스 정의

class 키워드를 사용해 정의한다. 파스칼 케이스를 사용하는 것이 일반적.

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

클래스는 함수다. 따라서 클래스는 값처럼 사용할 수 있는 일급 객체다.

따라서 표현식으로 정의할 수도 있다. 함수와 마찬가지로 이름을 갖거나 갖지 않을수 있다.

일급 객체로서 다음과 같은 특징을 갖는다.

  • 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.

  • 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.

  • 함수의 매개변수에 전달할 수 있다.

  • 함수의 반환값으로 사용할 수 있다.

클래스 몸체에는 메서드만 정의할 수 있는데, 정의 가능한 메서드는 constructor(생성자), 프로토타입 메서드, 정적 메서드 세 가지가 있다.

클래스와 생성자 함수의 정의 방식은 형태적인 면에서 매우 유사하다.


25.3 클래스 호이스팅

클래스는 함수로 평가된다.

// 클래스 선언문
class Persion {}
console.log(typeof Person) // function

클래스 선언문으로 정의한 클래스는 함수 선언문과 같이 런타임 이전에 먼저 평가되어 함수 객체를 생성한다. 이때 평가되어 생성된 함수 객체는 생성자 함수로서 호출할 수 있는 함수, constructor다. (프로토타입도 더불어 생성된다.)

클래스는 클래스 정의 이전에 참조할 수 없다.

console.log(Person)
// ReferenceError: Cannot access 'Person' befor initailization

class Person{}

클래스 선언문은 마치 호이스팅이 발생하지 않는 것처럼 보이나 그렇지 않다.

const Person = ''

{
	console.log(Person) // 호이스팅이 발생하지 않으면 ''이 출력되어야한다. 하지만,
	// ReferenceError: Cannot access 'Person' befor initailization

	class Person{}
}

클래스 선언문도 변수 선언, 함수 정의와 같이 호이스팅이 발생한다. let, const 키워드로 선언한 변수처럼 호이스팅된다. 클래스 선언문 이전에 일시적 사각지대에 빠지기에 발생하지 않는 것처럼 보이는것.


25.4 인스턴스 생성

클래스는 생성자 함수이며 new 연산자와 함께 호출되어 인스턴스를 생성한다.

class Person{}

// 인스턴스 생성
const me = new Person()
console.log(me) // Person {}

// new 없이 호출하면 타입 에러 발생
const you = Person()
// TypeError: Class constructor Foo cannot be invoked without 'new'

클래스는 인스턴스 생성이 유일한 존재 이유이므로 반드시 new 연산자와 호출해야 한다. 클래스 표현식으로 정의된 클래스를 식별자를 사용해 인스턴스를 생성하지 않고 클래스 이름으로 인스턴스를 생성하면 에러가 발생한다.

const Person = class Myclass{}

const me = new Person()
console.log(MyClass) // ReferenceError: MyClass is not defined

const you = new MyClass() // ReferenceError: MyClass is not defined

25.5 메서드

클래스 몸체에는 0개 이상의 메서드만 선언할 수 있다. 정의할 수 있는 메서드는 constructor, 프로토타입, 정적 메서드 총 3가지이다.

25.5.1 constructor

constructor는 인스턴스를 생성하고 초기화하기 위한 특수한 메서드다. - 이름 변경 불가능

class Person{
	constructor(name){
		this.name = name
	}
}

constructor는 함수 객체 코드의 일부가 된다. 클래스 내 최대 1개만 존재할 수 있으며, 생략시 빈 객체가 암묵적으로 정의된다.

프로퍼티가 추가되어 초기화된 인스턴스를 생성하려면 constructor 내부의 this에 인스턴스 프로퍼티를 추가하면 된다. 클래스 외부에서 초기값을 전달하려면 constructor에 매개변수를 선언하고, 인스턴스를 생성할 때 초기값을 전달하면 된다. 인스턴스를 초기화하려면 constructor를 생략해서는 안된다.

또한 constructor는 별도의 반환문을 갖지 않아야 한다. new 연산자와 함께 클래스가 호출되면 생성자 함수와 동일하게 암묵적으로 this, 인스턴스를 반환하기 때문이다. 만약, 명시적으로 다른 객체를 반환하면 명시한 객체가 반환된다. ( 명시적으로 원시값을 반환하면 무시됨 ) 따라서 반드시 constructor 내부에서 return 문을 반드시 생략해야 한다.

25.5.2 프로토타입 메서드

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

class Person{

	constructor(name){
		this.name = name
	}

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

const me = new Person('Lee')
me.sayHi() // Hi! My name is Lee

프로토타입 체인은 기본의 모든 객체 생성 방식뿐 아니라 클래스에 의해 생성된 인스턴스에도 동일하게 적용된다. 결국 클래스는 생성자 함수와 같이 인스턴스를 생성하는 생성자 함수라 볼 수 있다.

즉, 클래스는 프로토타입 기반의 객체 생성 메커니즘이다.

25.5.3 정적 메서드

정적 메서드는 인스턴스를 생성하지 않아도 호출 할 수 있는 메서드를 말한다.

클래스에서는 메서드에 static 키워드를 붙이면 정적 메서드가 된다.

class Person{
	constructor(name){
		this.name = name
	}

	static sayHi(){
		console.log("Hi!")
	}
}

Person.sayHi() // Hi!

25.5.4 정적 메서드와 프로토타입 메서드의 차이

  1. 정적 메서드와 프로토타입 메서드는 속해있는 프로토타입 체인이 다르다

  2. 정적 메서드는 클래스로 호출하고 프로토타입 메서드는 인스턴스로 호출한다.

  3. 정적 메서드는 인스턴스 프로퍼티를 참조할 수 없지만 프로토타입 메서드는 가능하다.

정적 메서드는 인스턴스를 사용하지 않을때 !, this를 사용하지 않을때!

프로토타입 메서드는 인스턴스를 사용할때 !, this를 사용해야할때 !

25.5.5 클래스에서 정의한 메서드의 특징

  1. function 키워드를 생략한 메서드 축약 표현을 사용한다.

  2. 객체 리터럴과 다르게 클래스에 메서드를 정의할 때는 콤마가 필요없다.

  3. 암묵적으로 strict mode로 실행된다.

  4. 열거할 수 없다. (for in 문이나 Object.keys 메서드 등)

  5. 내부 메서드 [[Construct]]를 갖지 않는 non-constructor다. 따라서 new 연산자와 함께 호출할 수 없다.


25.6 클래스의 인스턴스 생성 과정

new 연산자와 함께 클래스를 호출하면 클래스의 내부 메서드 [[Construct]] 가 호출된다. 그리고 다음과 같은 과정을 거쳐 인스턴스가 생성된다.

1️⃣ 인스턴스 생성과 this 바인딩

constructor 내부 코드가 실행되기 전 암묵적으로 빈 객체(클래스가 생성한 인스턴스)가 생성된다.

이때 클래스가 생성한 인스턴스의 프로토타입으로 클래스의 prototype 프로퍼티가 가리키는 객체가 설정된다. 그리고 암묵적으로 인스턴스는 this에 바인딩된다.

따라서 constructor 내부의 this는 클래스가 생성한 인스턴스를 가리키게 된다.

2️⃣ 인스턴스 초기화

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

this에 바인딩되어 있는 인스턴스에 프로퍼티를 추가하고 constructor가 인수로 받은 초기값으로 인스턴스의 프로퍼티 값을 초기화한다. (constructor가 생략되면 이 과정도 생략됨)

3️⃣ 인스턴스 반환

클래스의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this를 암묵적으로 반환된다.

class Person{
	constructor(name){
		// 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
		console.log(this) // Person {}
		console.log(Object.getPrototypeOf(this) === Person.prototype) // true

		// 2. this에 바인딩되어 있는 인스턴스를 초기화한다.
		this.name = name

		// 3. 완성된 인스턴스가 바인딩된 this를 암묵적으로 반환된다.
	}
}

25.7 프로퍼티

25.7.1 인스턴스 프로퍼티

인스턴스 프로퍼티는 constructor 내부에서 정의한다.

class Person{
	constructor(name){
		this.name = name
	}
}

const me = new Person('Lee')
console.log(me) // Person{neme: 'Lee'}

접근 제한자를 지원하지 않기에 언제나 public하다.

25.7.2 접근자 프로퍼티

다른 데이터 프로퍼티의 값을 읽거나 저장할때 사용하는 접근자 함수로 구성된 프로퍼티

class Person{
	constructor(fristName, lastName){
		this.firstName = firstName
		this.lastName = lastName
	}

	// getter 함수
	get fullName(){
		return `${this.firstName} ${this.lastName}`
	}

	// setter 함수
	set fullName(){
		[this.firstName, this.lastName] = name.split(' ')
	}
}

const me = new Person('BJ', 'HAN')
console.log(`${me.firstName}` ${me.lastName}) //BJ HAN

me.fullName = 'HM SON'
console.log(me) // {firstName: "HM", lastName: "SON"}

console.log(me.fullName) // HM SON

// fullName은 접근자 프로퍼티
console.log(Object.getOwnPropertyDescriptor(Person.prototype, 'fullName')
// {get: f, set: f, enumerable: false, configurable: true}

getter는 참조하기에 반드시 반환해야하고, setter는 할당하기에 반드시 매개변수가 있어야 한다.

클래스의 메서드는 기본적으로 프로토타입 메서드가 된다.

따라서 클래스의 접근자 프로퍼티 또한 프로토타입의 프로퍼티가 된다.

25.7.3 클래스 필드 정의 제안

(내용만 보면 이해 안되는데 예시를 보면 이해됨… 책 예시를 보자 !)

클래스 필드 - 클래스 기반 객체지향 언어에서 클래스가 생성할 인스턴스의 프로퍼티를 가르키는 용어.

최신 브라우저와 node.js에서 사용 가능함

class Person{
	// 클래스 필드 정의
	name = 'Lee'
}

const me = new Person()
console.log(me) // Person {name: "Lee"}

25.7.4 private 필드 정의 제안

JS는 캡슐화를 완전히 지원하지 않는다. 접근 제한자를 지원하지 않기에 인스턴스 프로퍼티는 언제나 public이다.

최신 브라우저와 node.js에서 사용 가능함

class Person{
	// private 필드 정의
	#name = ''

	constructor(name){
		// private 필드 참조
		this.#name = name
	}
}

const me = new Person('Lee')
console.log(me.#name) //SyntaxError : private field '#name' ~~

클래스 몸체에서 private 필트의 선두에 #을 붙여 사용한다. 참조시에도 #을 붙임

클래스 내부에서만 참조할 수 있고, 반드시 클래스 몸체에 정의해야 한다.

(접근자 프로퍼티로 간접 접근할 수 있음..!)

25.7.5 static 필드 정의 제안

static 키워드를 사용해 정적 메서드를 정의할 수 있다.

최신 브라우저와 node.js에서 사용 가능

class MyMath{}
	// static public 필드 정의
	static PI = 22 / 7

	// static private 필드 정의
	static #num = 10

	// static 메서드
	static increment(){
		return ++MyMath.#num
	}
}

console.log(MyMath.PI) // 3.142857...
console.log(MyMath.increment()) // 11

25.8 상속에 의한 클래스 확장

25.8.1 클래스 상속과 생성자 함수 상속

상속에 의한 클래스 확장은 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의하는 것.

extends 키워드를 사용해 상속할 수 있다.

25.8.2 extends 키워드

상속을 통해 클래스를 확장하려면 extends 키워드를 사용해 상속받을 클래스를 정의한다.

// 수퍼(베이스/부모) 클래스
class Base{}

// 서브(파생/자식) 클래스
class Derived extends Base{}

extends 키워드는 수퍼 클래스와 서브 클래스 간 상속 관계를 설정한다. (프로토타입을 통해 상속 관계를 구현한다.)

수퍼 클래스와 서브 클래스는 인스턴스의 프로토타입 체인과 클래스 간 프로토타입 체인도 생성한다. 이를 통해 프로토타입 메서드와 정적 메서드 모두 상속이 가능하다.

25.8.3 동적 상속

extends 키워드는 클래스 뿐 아니라 생성자 함수를 상속받아 클래스를 확장할 수 있다. 단, extends 키워드 앞에는 반드시 class가 와야 한다.

// 생성자 함수
function Base(a){
	this.a = a
}

// 생성자 함수를 상속받는 서브클래스
class Derived extends Base {}

const derived = new Derived(1)
console.log(derived) // Derived {a:1}

extends 키워드 다음에는 [[Construct]] 내부 메서드를 갖는 모든 표현식을 사용할 수 있다. 이를 통해 동적으로 상속받을 대상을 결정할 수 있다.

function Base1(){}
class Base2{}
let condition = true

class Derived extends (condition ? Base1 : Base2) {}

const derived = new Derived()
console.log(derived)

console.log(derived instanceof Base1) // true
console.log(derived instanceof Base2) // false

25.8.4 서브클래스의 constructor

클래스에서 constructor를 생략하면 비어있는 constructor가 암묵적으로 정의된다.

// 수퍼클래스
class Base{}

// 서브클래스
class Derived extends Base{}

// 위와 코드는 아래와 같이 암묵적으로 constructor 가 정의된다.

// 수퍼클래스
class Base{
	constructor(){}
}

// 서브클래스
class Derived extends Base{
	constructor(...args) {super(...args}}
}

const derived = new Derived()
console.log(derived) // Derived{}

args는 new 연산자와 함께 클래스를 호출할 때 전달한 인수의 리스트다.

super()는 수퍼클래스의 constructor를 호출하여 인스턴스를 생성한다.

25.8.5 super 키워드

super 키워드는 함수처럼 호출할 수도 있고, 식별자처럼 참조할 수 있는 특수한 키워드다.

super 호출

super를 호출하면 수퍼클래스의 constructor를 호출한다.

수퍼클래스의 프로퍼티를 그대로 갖는 인스턴스라면 서브클래스의 constructor를 생략할 수 있다.

하지만, 수퍼클래스의 프로퍼티와 서브클래스에서 추가한 프로퍼티를 갖는 인스턴스를 생성한다면 constructor를 생략할 수 없다. 수퍼클래스의 constructor에 전달할 필요가 있는 인수는 super를 통해 전달한다.

// super
class Base{
	constructor(a,b){
		this.a = a
		this.b = b
	}
}

// sub
class Derived extends Base{
	constructor(a,b,c){
		super(a,b)
		this.c = c
	}
}

const derived = new Derived(1,2,3)
console.log(derived) // Derived {a:1, b:2, c:3}

이처럼 인스턴스 초기화를 위해 전달한 인수는 수퍼클래스와 서브클래스에 배분되고, 상속 관계의 두 클래스는 서로 협력하여 인스턴스를 생성한다.

super 호출시 주의사항

  • 서브클래스에서 constructor를 생략하지 않는 경우, 서브 클래스의 constructor에 반드시 super를 호출해야 한다.

  • 서브클래스의 constructor에서 super를 호출하기 전에는 this를 참조할 수 없다.

  • super는 반드시 서브클래스의 constructor에서만 호출한다.

super 참조

메서드 내에서 super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다.

책으로 확인..! p.457 ~ p.460

25.8.6 상속 클래스의 인스턴스 생성 과정

  1. 서브클래스의 super 호출 ㄴ JS 엔진은 클래스를 평가할 때 내부 슬롯 [[ConstructorKind]]에 수퍼와 서브를 구분한다. ㄴ 수퍼 클래스는 인스턴스를 생성하고 this를 반환한다. ㄴ 서브 클래스는 인스턴스 생성을 수퍼 클래스에 위임한다. ㄴ 서브의 constructor에 반드시 super를 호출해야하는 이유 !!

  2. 수퍼클래스의 인스턴스 생성과 this 바인딩 ㄴ 생성된 인스턴스에 this 바인딩 ㄴ 수퍼 클래스가 생성했지만 서브 클래스가 생성한 인스턴스로 처리된다.

  3. 수퍼클래스의 인스턴스 초기화 ㄴ 수퍼의 constructor가 실행되어 this에 바인딩된 인스턴스를 초기화한다.

  4. 서브클래스 constructor 복귀와 this 바인딩 ㄴ super의 호출이 종료되고 반환한 인스턴스가 this에 바인딩된다. 이 인스턴스에 this를 바인딩해 그대로 사용한다. ㄴ 서브의 constructor에서 super 호출 전 this를 참조할 수 없는 이유 !!

  5. 서브클래스 인스턴스 초기화 ㄴ super 호출 이후 서브의 constructor에 기술된 인스턴스 초기화가 실행된다.

  6. 인스턴스 반환 ㄴ 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.

25.8.7 표준 빌트인 생성자 함수 확장

extends 키워드 다음에는 클래스뿐 아니라 [[Construct]] 내부 메서드를 갖는 모든 표현식을 사용할 수 있다. String, Number, Array 같은 표준 빌트인 객체도 사용할 수 있다.

Previous24장 클로저 ⭐⭐⭐⭐⭐⭐⭐Next26장 ES6 함수의 추가 기능

Last updated 1 year ago

Was this helpful?

📚