λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
javascript/πŸ“– study

[5μ£Όμ°¨ μŠ€ν„°λ””]25μž₯-클래슀

by HomieKim 2022. 3. 27.

클래슀

문법적 섀탕(Syntactic Sugar)

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž… 기반의 객체지ν–₯ μ–Έμ–΄λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.
  • es6μ—μ„œ λ„μž…λœ ν΄λž˜μŠ€λŠ” 클래슀 기반 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ° 언어와 맀우 ν‘μ‚¬ν•œ 객체 생성 λ©”μ»€λ‹ˆμ¦˜μ„ μ œμ‹œν•©λ‹ˆλ‹€.
  • 사싀 ν΄λž˜μŠ€λŠ” 객체 지ν–₯ λͺ¨λΈμ„ μ œκ³΅ν•˜λŠ” 것이 μ•„λ‹Œ ν•¨μˆ˜μ΄λ©° ν”„λ‘œν† νƒ€μž… 기반 νŒ¨ν„΄μ„ 클래슀 기반 νŒ¨ν„΄ 처럼 μ‚¬μš©ν•  수 있게 ν•˜λŠ” 문법적 섀탕(Syntactic Sugar) 이라고 λ³Ό 수 μžˆλ‹€.
  • ν΄λž˜μŠ€λŠ” μƒμ„±μž ν•¨μˆ˜μ™€ 맀우 μœ μ‚¬ν•˜κ²Œ λ™μž‘ν•˜μ§€λ§Œ λͺ‡ 가지 차이가 μžˆλ‹€.
    1. 클래슀λ₯Ό newν‚€μ›Œλ“œ 없이 호좜 ν•˜λ©΄ μ—λŸ¬, μƒμ„±μž ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜λ‘œ 호좜됨
    2. ν΄λž˜μŠ€λŠ” 상속을 μ§€μ›ν•˜λŠ” extends와 super ν‚€μ›Œλ“œλ₯Ό 제곡
    3. ν΄λž˜μŠ€λŠ” ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” 것 처럼 λ™μž‘, (ν•¨μˆ˜λŠ” ν•¨μˆ˜ μ„ μ–Έλ¬Έ 으둜 μ •μ˜ 된 μƒμ„±μžν•¨μˆ˜λŠ” ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…, ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ μ •μ˜ν•œ μƒμ„±μž ν•¨μˆ˜λŠ” λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ… λ°œμƒ)
    4. 클래슀 λ‚΄μ˜ λͺ¨λ“  μ½”λ“œμ—λŠ” μ•”λ¬΅μ μœΌλ‘œ strict mode
    5. 클래슀의 λ©”μ„œλ“œλŠ” μ—΄κ±°λ˜μ§€ μ•ŠλŠ”λ‹€.
  • 클래슀λ₯Ό λ‹¨μˆœν•œ 문법적 μ„€νƒ•μœΌλ‘œ 보기 λ³΄λ‹€λŠ” μƒˆλ‘œμš΄ 객체 생성 λ©”μ»€λ‹ˆμ¦˜ 으둜 λ³΄λŠ” 것이 ν•©λ‹Ή

클래슀의 μ •μ˜

  • ν΄λž˜μŠ€λŠ” classν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜ν•¨
  • ν΄λž˜μŠ€λŠ” 일급 객체 이며 ν•¨μˆ˜
  • 클래슀 λͺΈμ²΄μ— μ •μ˜ν•  수 μžˆλŠ” λ©”μ„œλ“œλŠ” 3가지
    1. constructor(μƒμ„±μž)
    2. ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ
    3. 정적 λ©”μ„œλ“œ

클래슀 ν˜Έμ΄μŠ€νŒ…

  • ν΄λž˜μŠ€λŠ” ν•¨μˆ˜λ‘œ 평가 λœλ‹€.
  • 클래슀 μ„ μ–Έ 문으둜 μ •μ˜ν•œ ν΄λž˜μŠ€λŠ” ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό 같이 λŸ°νƒ€μž„ 이전에 μ†ŒμŠ€μ½”λ“œ 평가 과정을 거쳐 ν•¨μˆ˜ 객체λ₯Ό 생성함
class Person {}

console.log(typeof Person);
  • μ΄λ•Œ μƒμ„±λœ μƒμ„±μžλŠ” constructor( μƒμ„±μžμ™€ ν”„λ‘œν† νƒ€μž…μ€ 쌍으둜 μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— μ΄λ•Œ ν”„λ‘œν†  νƒ€μž…λ„ 생성됨)
  • 단, ν΄λž˜μŠ€λŠ” μ •μ˜ 이전에 μ°Έμ‘° ν•  수 μ—†λ‹€.
  • ν˜Έμ΄μŠ€νŒ…μ΄ λ˜μ§€ μ•Šμ€ 것 처럼 λ³΄μ΄λ‚˜ μ΄λŠ” let, const 처럼 TDZκ°œλ…μ΄ μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έ

μΈμŠ€ν„΄μŠ€ 생성

  • ν΄λž˜μŠ€λŠ” μƒμ„±μž ν•¨μˆ˜ μ΄λ―€λ‘œ newμ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœλ˜μ–΄ μΈμŠ€ν„΄μŠ€λ₯Ό 생성
class Person {}

const me = new Person();
  • κΈ°λͺ… ν•¨μˆ˜ ν‘œν˜„μ‹κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 클래슀 ν‘œν˜„μ‹μ— μ„œγ…μš©ν•œ 클래슀 이름은 μ™ΈλΆ€ μ½”λ“œμ—μ„œ μ ‘κ·Ό λΆˆκ°€λŠ₯
const Person = class MyClass {};

// ν•¨μˆ˜ ν‘œν˜„μ‹κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 클래슀λ₯Ό κ°€λ¦¬ν‚€λŠ” μ‹λ³„μžλ‘œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성해야 ν•œλ‹€.
const me = new Person();

// 클래슀 이름 MyClassλŠ” ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ 클래슀 λͺΈμ²΄ λ‚΄λΆ€μ—μ„œλ§Œ μœ νš¨ν•œ μ‹λ³„μžλ‹€.
console.log(MyClass); // ReferenceError: MyClass is not defined

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

λ©”μ„œλ“œ

  • 클래슀 λͺΈμ²΄μ—μ„œ μ •μ˜ν•  수 μžˆλŠ” λ©”μ„œλ“œ 3가지
    1. constructor(μƒμ„±μž)
    2. ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ
    3. 정적 λ©”μ„œλ“œ

constructor

  • μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  μ΄ˆκΈ°ν™”ν•˜κΈ° μœ„ν•œ νŠΉμˆ˜ν•œ λ©”μ„œλ“œ(이름 λ³€κ²½ λΆˆκ°€)
  • constructorλ‚΄λΆ€μ˜ thisλŠ” μƒμ„±μž ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀.
  • constructorλŠ” λ©”μ„œλ“œλ‘œ ν•΄μ„λ˜λŠ” 것이 μ•„λ‹ˆλΌ, ν΄λž˜μŠ€κ°€ ν‰κ°€λ˜μ–΄ μƒμ„±λœ ν•¨μˆ˜ 객체의 μ½”λ“œμ˜ 일뢀가 됨클래슀 μ •μ˜κ°€ ν‰κ°€λ˜λ©΄ constructor의 기술된 λ™μž‘μ„ ν•˜λŠ” ν•¨μˆ˜ 객체가 생성
    클래슀의 constructor λ©”μ„œλ“œμ™€ ν”„λ‘œν† νƒ€μž…μ˜ constructor ν”„λ‘œνΌν‹°λŠ” 직접 적인 κ΄€λ ¨ μ—†λ‹€.
    ν”„λ‘œν† νƒ€μž…μ˜ constructor ν”„λ‘œνΌν‹°λŠ” λͺ¨λ“  ν”„λ‘œν† νƒ€μž…μ΄ 가지고 μžˆλŠ” ν”„λŸ¬νΌν‹° 이며, μƒμ„±μž ν•¨μˆ˜λ₯Ό 가리킨닀.

constructorλŠ” μƒμ„±μž ν•¨μˆ˜μ™€ μœ μ‚¬ν•˜μ§€λ§Œ 차이가 μžˆλ‹€.

  • constructorλŠ” ν΄λž˜μ„œ 내에 μ΅œλŒ€ ν•œ 개만 쑴재 κ°€λŠ₯
  • constructorλŠ” μƒλž΅ κ°€λŠ₯ (μƒλž΅μ‹œ 빈 constructorκ°€ μ•”λ¬΅μ μœΌλ‘œ μ •μ˜ 됨)
  • constructorλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό 생성과 λ™μ‹œμ— ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™” ν•©λ‹ˆλ‹€.

곡톡점 : λ³„λ„μ˜ λ°˜ν™˜(return) 을 갖지 μ•Šμ•„μ•Όν•¨, μ•”λ¬΅μ μœΌλ‘œ this λ°˜ν™˜

ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ

  • 클래슀 λͺΈμ²΄μ—μ„œ μ •μ˜ν•œ λ©”μ„œλ“œλŠ” μƒμ„±μž ν•¨μˆ˜ 방식과 달리 ν΄λž˜μ„œμ˜ 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
  • μƒμ„±μž ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œν† νƒ€μž… 체인의 일원이 λœλ‹€.
  • 정리 : ν΄λž˜μŠ€λŠ” μƒμ„±μž ν•¨μˆ˜μ™€ 같이 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” μƒμ„±μž ν•¨μˆ˜λΌκ³  λ³Ό 수 μžˆλ‹€. 즉, ν΄λž˜μŠ€λŠ” ν”„λ‘œν† νƒ€μž… 기반의 객체 생성 λ©”μ»€λ‹ˆμ¦˜ 이닀.

정적 λ©”μ„œλ“œ

  • 정적(static)λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ 호좜 ν•  수 μžˆλŠ” λ©”μ„œλ“œλ₯Ό λ§ν•œλ‹€.
  • μƒμ„±μž ν•¨μˆ˜ 경우 정적 λ©”μ„œλ“œλ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ λͺ…μ‹œμ μœΌλ‘œ μƒμ„±μž ν•¨μˆ˜μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.
  • ν΄λž˜μŠ€μ—μ„œλŠ” λ©”μ„œλ“œμ— static ν‚€μ›Œλ“œλ₯Ό 뢙이면 정적 λ©”μ„œλ“œ(클래슀 λ©”μ„œλ“œ)κ°€ λœλ‹€.
class Person {
  // μƒμ„±μž
  constructor(name) {
    // μΈμŠ€ν„΄μŠ€ 생성 및 μ΄ˆκΈ°ν™”
    this.name = name;
  }

  // 정적 λ©”μ„œλ“œ
  static sayHi() {
    console.log('Hi!');
  }
}
  • 정적 λ©”μ„œλ“œλŠ” ν΄λž˜μŠ€μ— λ°”μΈλ”©λœ λ©”μ„œλ“œκ°€ λœλ‹€.

정적 λ©”μ„œλ“œμ™€ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œμ˜ 차이

  1. 정적 λ©”μ„œλ“œμ™€ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μžμ‹ μ΄ 속해 μžˆλŠ” ν”„λ‘œν† νƒ€μž… 체인이 λ‹€λ₯΄λ‹€
  2. 정적 λ©”μ„œλ“œλŠ” 클래슀둜 ν˜ΈμΆœν•˜κ³  ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ‘œ 호좜
  3. 정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μ—†μ§€λ§Œ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.this 바인딩 원리에 따라 정적 λ©”μ„œλ“œλŠ” 클래슀둜 호좜 ν•˜κΈ° λ•Œλ¬Έμ— λ‚΄λΆ€μ˜ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘° ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
    thisλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μ •μ λ©”μ„œλ“œλ‘œ μ •μ˜ν•˜λŠ” 것도 μ’‹μŒ

ν΄λž˜μŠ€μ—μ„œ μ •μ˜ν•œ λ©”μ„œλ“œμ˜ νŠΉμ§•

  1. function ν‚€μ›Œλ“œλ₯Ό μƒλž΅ν•œ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„ μ‚¬μš©.
  2. 객체 λ¦¬ν„°λŸ΄κ³Ό λ‹€λ₯΄κ²Œ μ½€λ§ˆκ°€ ν•„μš” μ—†μŒ.
  3. μ•”λ¬΅μ μœΌλ‘œ strict mode둜 μ‹€ν–‰.
  4. for ... in λ¬Έμ΄λ‚˜ Object.keys λ©”μ„œλ“œ λ“±μœΌλ‘œ μ—΄κ±°ν•  수 μ—†μŒ.
  5. λ‚΄λΆ€ λ©”μ„œλ“œ [[Construct]]λ₯Ό 갖지 μ•ŠλŠ” non-constructor. λ”°λΌμ„œ new μ—°μ‚°μžμ™€ ν•¨κ»˜ 호좜 λΆˆκ°€.

클래슀 μΈμŠ€ν„΄μŠ€ 생성 κ³Όμ •

  1. μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩
    • new μ—°μ‚°μžμ™€ ν•¨κ»˜ 클래슀λ₯Ό ν˜ΈμΆœν•˜λ©΄ constructor λ‚΄λΆ€ μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ°μ— μ•žμ„œ μ•”λ¬΅μ μœΌλ‘œ 빈 객체 생성.
    • 이 빈 객체가 ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€κ°€ 됨.
    • μ΄λ•Œ, ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž…μœΌλ‘œ 클래슀의 prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” 객체 μ„€μ •.
    • μ•”λ¬΅μ μœΌλ‘œ μƒμ„±λœ 빈 객체. 즉, μΈμŠ€ν„΄μŠ€λŠ” this에 바인딩.λ”°λΌμ„œ constructor λ‚΄λΆ€μ˜ thisλŠ” ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό 가리킴.
  2. μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
    • constructor의 λ‚΄λΆ€ μ½”λ“œκ°€ μ‹€ν–‰ this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
    • constructorκ°€ μƒλž΅ λ˜μ—ˆλ‹€λ©΄ 이 과정도 μƒλž΅ 됨
  3. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜
    • 클래슀의 λͺ¨λ“  μ²˜λ¦¬κ°€ λλ‚˜λ§Œ μΈμŠ€ν„΄μŠ€κ°€ 바인딩 된 thisκ°€ 암묡 적으둜 λ°˜ν™˜

ν”„λ‘œνΌν‹°

μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°

  • μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λŠ” constructor내뢀에 μ •μ˜ κ°€λŠ₯
  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” μ ‘κ·Όμ œν•œμžλ₯Ό μ§€μ›ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λŠ” public

μ ‘κ·Όμž ν”„λ‘œνΌν‹°

μ ‘κ·Όμž ν”„λ‘œνΌν‹°λž€?
자체적으둜 κ°’([[ Value ]]λ‚΄λΆ€μŠ¬λ‘―)을 갖지 μ•Šκ³  데이터 ν”„λ‘œνΌν‹°μ˜ 값을 μ½κ±°λ‚˜ μ €μž₯ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ ‘κ·Όμž ν•¨μˆ˜λ‘œ κ΅¬μ„±λœ ν”„λ‘œνΌν‹°

  • 예제
// 객체 λ¦¬ν„°λŸ΄ 방식
const person = {
    // 데이터 ν”„λ‘œνΌν‹°
    firstName : 'homie',
    lastName : 'kim',

    // μ ‘κ·Όμž ν”„λ‘œνΌν‹°
    get fullName() {
        return `${this.fristname} ${this.lastName}`;
    },
    set fullName(name) {
        [this.firstName, this.lastName] = name.split(' ');
    }
};        

// class 방식
class Person {
    // 데이터 ν”„λ‘œνΌν‹°
    constructor(firstName, lastName) {
        this.firstName =firstName;
        this.lastName = lastName;
    }
    // μ ‘κ·Όμž ν”„λ‘œνΌν‹°
    get fullName() {
        return `${this.fristname} ${this.lastName}`;
    }
    set fullName(name) {
        [this.firstName, this.lastName] = name.split(' ');
    }    
};
const me = new Person('Homie Kim');    
  • 클래슀의 λ©”μ„œλ“œλŠ” 기본적으둜 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œκ°€ λ©λ‹ˆλ‹€. μ ‘κ·Όμž ν”„λ‘œνΌν‹° λ˜ν•œ ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°μ΄λ‹€.

private ν•„λ“œ μ •μ˜ μ œμ•ˆ

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 클래슀의 ν”„λ‘œνΌν‹°λŠ” 기본적으둜 public μž…λ‹ˆλ‹€.
  • μ΅œμ‹  μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” privateλ₯Ό μ •μ˜ ν•  수 μžˆλŠ” ν‘œμ€€ 사양이 μƒˆλ‘­κ²Œ μ œμ•ˆ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
class Person {
  // private ν•„λ“œ μ •μ˜, pirvate ν•„λ“œλŠ” λ°˜λ“œμ‹œ 클래슀 λͺΈμ²΄μ—μ„œ μ •μ˜ λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.(μƒμ„±μž λ‚΄λΆ€λŠ” μ•ˆλ¨)
  #name = '';

  constructor(name) {
    this.#name = name;
  }

  // name은 μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‹€.
  get name() {
    // private ν•„λ“œλ₯Ό μ°Έμ‘°ν•˜μ—¬ trimν•œ λ‹€μŒ λ°˜ν™˜ν•œλ‹€.
    return this.#name.trim();
  }
}

const me = new Person(' Lee ');
console.log(me.name); // Lee

상속에 μ˜ν•œ 클래슀 ν™•μž₯

  • ν”„λ‘œν† νƒ€μž… 기반의 상속은 ν”„λ‘œν† νƒ€μž… 체인을 톡해 λ‹€λ₯Έ 객체의 μžμ‚°μ„ μƒμ†λ°›λŠ” κ°œλ…
  • 상속에 μ˜ν•œ 클래슀 ν™•μž₯은 κΈ°μ‘΄ 클래슀λ₯Ό 상속받아 μƒˆλ‘œμš΄ 클래슀λ₯Ό ν™•μž₯ν•˜μ—¬ μ •μ˜ν•˜λŠ” 것
  • extendsν‚€μ›Œλ“œλ₯Ό μ œκ³΅ν•˜μ—¬ 상속을 κ΅¬ν˜„ν•©λ‹ˆλ‹€.

extends ν‚€μ›Œλ“œ

// 수퍼(베이슀/λΆ€λͺ¨)클래슀
class Base {}

// μ„œλΈŒ(νŒŒμƒ/μžμ‹) 클래슀
class Derived extends Base {}
  • ν΄λž˜μŠ€λ„ λ‚΄λΆ€μ μœΌλ‘œλŠ” ν”„λ‘œν† νƒ€μž…μ„ 톡해 상속 관계λ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.
  • μˆ˜νΌν΄λž˜μŠ€μ™€ μ„œλΈŒν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž… 체인 뿐 μ•„λ‹ˆλΌ ν΄λž˜μŠ€κ°„μ˜ ν”„λ‘œν†  νƒ€μž… 체인도 μƒμ„±ν•©λ‹ˆλ‹€.
  • 이λ₯Ό 톡해 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ, 정적 λ©”μ„œλ“œ λͺ¨λ‘ 상속이 κ°€λŠ₯

동적 상속

  • extendsν‚€μ›Œλ“œλŠ” 클래슀 뿐만 μ•„λ‹ˆλΌ μƒμ„±μž ν•¨μˆ˜λ₯Ό 상속받아 클래슀λ₯Ό ν™•μž₯ν•  μˆ˜λ„ μžˆλ‹€.
// μƒμ„±μž ν•¨μˆ˜
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); // Derived {}

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

μ„œλΈŒ 클래슀의 constructor

  • ν΄λž˜μŠ€μ—μ„œ constructorλ₯Ό μƒλž΅ν•˜λ©΄ μ•”λ¬΅μ μœΌλ‘œ 생성이 λ©λ‹ˆλ‹€.
  • μ„œλΈŒ ν΄λž˜μŠ€μ—μ„œ constructorλ₯Ό μƒλž΅ν•˜λ©΄ 수퍼 클래슀의 constructorλ₯Ό ν˜ΈμΆœν•˜μ—¬ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
// 수퍼클래슀
class Base {}

// μ„œλΈŒν΄λž˜μŠ€
class Derived extends Base {
 // μƒλž΅ μ‹œ λ‹€μŒκ³Ό 같은 μƒμ„±μž 호좜 됨
  constructor(...args) { super(...args); }
}

super ν‚€μ›Œλ“œ

  • superν‚€μ›Œλ“œλŠ” ν•¨μˆ˜μ²˜λŸΌ ν˜ΈμΆœν•  μˆ˜λ„ 있고 this와 같이 μ‹λ³„μž 처럼 μ°Έμ‘°ν•  수 μžˆλŠ” νŠΉμˆ˜ν•œ ν‚€μ›Œλ“œμ΄λ‹€.
  • superλ₯Ό ν˜ΈμΆœν•˜λ©΄ 수퍼클래슀의 constructorλ₯Ό 호좜 ν•œλ‹€.
    superλ₯Ό μ°Έμ‘°ν•˜λ©΄ 수퍼클래슀의 λ©”μ†Œλ“œλ₯Ό 호좜 ν•  수 μžˆλ‹€.
  • super ν˜ΈμΆœμ‹œ 주의 사항
    1. μ„œλΈŒν΄λž˜μŠ€μ—μ„œ constructorλ₯Ό μƒλž΅ν•˜μ§€ μ•ŠλŠ” 경우 μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œλŠ” λ°˜λ“œμ‹œ superλ₯Ό 호좜 ν•΄μ•Ό ν•œλ‹€.
    2. μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜κΈ° μ „μ—λŠ” thisλ₯Ό μ°Έμ‘°ν•  수 μ—†λ‹€.
    3. superλŠ” λ°˜λ“œμ‹œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œλ§Œ ν˜ΈμΆœν•œλ‹€. μ„œλΈŒ ν΄λž˜μŠ€κ°€ μ•„λ‹Œ 클래슀의 constructorλ‚˜ ν•¨μˆ˜μ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜λ©΄ μ—λŸ¬
  • superλ₯Ό μ°Έμ‘°ν•˜λ©΄ 수퍼클래슀의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

상속 클래슀의 μΈμŠ€ν„΄μŠ€ 생성 κ³Όμ •

  1. μ„œλΈŒ 클래슀의 super호좜
    • μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 클래슀λ₯Ό 평가할 λ•Œ μˆ˜νΌν΄λž˜μŠ€μ™€ μ„œλΈŒν΄λž˜μŠ€λ₯Ό κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ base λ˜λŠ” derivedλ₯Ό κ°’μœΌλ‘œ κ°–λŠ” λ‚΄λΆ€μŠ¬λ‘― [[ ConstructorKind ]]λ₯Ό κ°–λŠ”λ‹€.
    • λ‹€λ₯Έ 클래슀λ₯Ό 상속받지 μ•ŠλŠ” ν΄λž˜μŠ€λŠ” λ‚΄λΆ€ 슬둯 [[ConstructorKind]]의 값이 "base".
    • λ‹€λ₯Έ 클래슀λ₯Ό 상속 λ°›λŠ” μ„œλΈŒ ν΄λž˜μŠ€λŠ” λ‚΄λΆ€ 슬둯 [[ConstructorKind]]의 값이 "derived".
    • μ„œλΈŒν΄λž˜μŠ€λŠ” μžμ‹ μ΄ 직접 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ , μˆ˜νΌν΄λž˜μŠ€μ—κ²Œ μΈμŠ€ν„΄μŠ€ 생성을 μœ„μž„ν•œλ‹€.μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ λ°˜λ“œμ‹œ super λ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” 이유
    • μ„œλΈŒν΄λž˜μŠ€μ—μ„œ superκ°€ 호좜되면 수퍼 클래슀의 constructor 호좜
  2. 수퍼클래슀의 μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩
    • 수퍼클래슀의 constructor λ‚΄λΆ€ μ½”λ“œ μ‹€ν–‰ 되기 이전에 μ•”λ¬΅μ μœΌλ‘œ 빈 객체 생성
    • μˆ˜νΌν΄λž˜μŠ€κ°€ μƒμ„±ν•œ 빈 객체가 즉, μΈμŠ€ν„΄μŠ€λŠ” this에 바인딩됨
    • μƒμ„±λœ μΈμŠ€ν„΄μŠ€λŠ” μˆ˜νΌν΄λž˜μŠ€κ°€ μƒμ„±ν•œ 것 μ΄μ§€λ§Œ newμ—°μ‚°μžμ™€ 호좜된 ν΄λž˜μŠ€κ°€ μ„œλΈŒ ν΄λž˜μŠ€μ΄λ―€λ‘œ new 와 ν•¨κ»˜ 호좜된 ν•¨μˆ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” new.target은 μ„œλΈŒν΄λž˜μŠ€λ₯Ό 가리킴
  3. 수퍼클래슀의 μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
    • 수퍼클래슀의 constructorκ°€ μ‹€ν–‰ λ˜μ–΄ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”
  4. μ„œλΈŒν΄λž˜μŠ€ constructor둜의 볡귀와 this 바인딩
    • super의 호좜이 μ’…λ£Œλ˜κ³  λ‹€μ‹œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructor둜 λŒμ•„μ˜΄
    • μ΄λ•Œ superκ°€ λ°˜ν™˜ν•œ μΈμŠ€ν„΄μŠ€κ°€ this에 바인딩 됨
    • μ„œλΈŒν΄λž˜μŠ€λŠ” λ³„λ„μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  superκ°€ λ°˜ν™˜ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό this에 λ°”μΈλ”©ν•˜μ—¬ κ·ΈλŒ€λ‘œ μ‚¬μš©
  5. μ„œλΈŒν΄λž˜μŠ€μ˜ μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
    • μ„œλΈŒν΄λž˜μŠ€μ˜ constructorκ°€ μ‹€ν–‰λ˜λ©΄μ„œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹° μ΄ˆκΈ°ν™”
  6. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜
    • 바인딩 된 thisκ°€ μ•”λ¬΅μ μœΌλ‘œ λ°˜ν™˜

λŒ“κΈ€