πŸ“‹ λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive | 25μž₯ 클래슀

waterglassesΒ·2022λ…„ 5μ›” 28일
0
post-thumbnail

λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive λ„μ„œμ˜ 25μž₯을 μ •λ¦¬ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

25.1 ν΄λž˜μŠ€λŠ” ν”„λ‘œν† νƒ€μž…μ˜ 문법적 섀탕인가?

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž… 기반 객체지ν–₯ μ–Έμ–΄λ‹€. ES6μ—μ„œ λ„μž…λœ ν΄λž˜μŠ€λŠ” 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ° 언어와 맀우 ν‘μ‚¬ν•œ μƒˆλ‘œμš΄ 객체 생성 λ©”μ»€λ‹ˆμ¦˜μ„ μ œμ‹œν•œλ‹€. 사싀 ν΄λž˜μŠ€λŠ” ν•¨μˆ˜μ΄λ©° κΈ°μ‘΄ ν”„λ‘œν† νƒ€μž… 기반 νŒ¨ν„΄μ„ 클래슀 기반 νŒ¨ν„΄μ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜λŠ” 문법적 섀탕(더 μ‰½κ²Œ μ½κ±°λ‚˜ ν‘œν˜„ν•  수 μžˆλ„λ‘ μ„€κ³„λœ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ λ‚΄μ˜ ꡬ문)이라고 λ³Ό μˆ˜λ„ μžˆλ‹€.

ν΄λž˜μŠ€μ™€ μƒμ„±μž ν•¨μˆ˜λŠ” λͺ¨λ‘ ν”„λ‘œν† νƒ€μž… 기반의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€λ§Œ μ €ν™•νžˆ λ™μΌν•˜κ²Œ λ™μž‘ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€. 클래슀λ₯Ό λ‹¨μˆœν•œ 문법적 섀탕이라고 λ³΄κΈ°λ³΄λ‹€λŠ” μƒˆλ‘œμš΄ 객체 생성 λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œ λ³΄λŠ” 것이 μ’€ 더 ν•©λ‹Ήν•˜λ‹€.

25.2 클래슀 μ •μ˜

  • class ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜ν•œλ‹€.
  • μƒμ„±μž ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 파슀칼 μΌ€μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.
  • 클래슀λ₯Ό ν‘œν˜„μ‹μœΌλ‘œ μ •μ˜ν•  μˆ˜λ„ μžˆλ‹€
    - ν΄λž˜μŠ€κ°€ κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλŠ” 일급 κ°μ²΄λΌλŠ” 것을 μ˜λ―Έν•œλ‹€.
    - λŸ°νƒ€μž„μ— 생성이 κ°€λŠ₯ν•˜λ‹€.
    - λ³€μˆ˜λ‚˜ μžλ£Œκ΅¬μ‘°μ— μ €μž₯ν•  수 μžˆλ‹€.
    - ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ—κ²Œ 전달할 수 μžˆλ‹€.
    - ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

클래슀 λͺΈμ²΄μ—λŠ” 0개 μ΄μƒμ˜ λ©”μ„œλ“œλ§Œ μ •μ˜ν•  수 μžˆλ‹€.

class Person {
  // μƒμ„±μž
  constructor(name) {
    this.name = name // name ν”„λ‘œνΌν‹°λŠ” publicν•˜λ‹€.
  }
  
  // ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ
  sayHi() {
    console.log(`Hi! My name is ${this.name}`)
  }
  
  // 정적 λ©”μ„œλ“œ
  static sayHello() {
    console.log(`Hello!~`)
  }
}

// μΈμŠ€ν„΄μŠ€ 생성
const me = new person('Lee')

// μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹° μ°Έμ‘°
console.log(me.name) // Lee
// ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ 호좜
me.sayHi() // Hi! My name is Lee
// 정적 λ©”μ„œλ“œ 호좜
Person.sayHello() // Hello

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

ν΄λž˜μŠ€λŠ” ν•¨μˆ˜λ‘œ ν‰κ°€λœλ‹€.

class Person {}

console.log(typeof Person) // function

클래슀 μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜ν•œ ν΄λž˜μŠ€λŠ” ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό 같이 μ†ŒμŠ€μ½”λ“œ 평가 κ³Όμ •, 즉 λŸ°νƒ€μž„ 이전에 λ¨Όμ € ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체λ₯Ό μƒμ„±ν•œλ‹€. μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  수 μžˆλŠ” ν•¨μˆ˜λŠ” ν•¨μˆ˜ μ •μ˜κ°€ ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체λ₯Ό μƒμ„±ν•˜λŠ” μ‹œμ μ— ν”„λ‘œν† νƒ€μž…λ„ λ”λΆˆμ–΄ μƒμ„±λœλ‹€. ν”„λ‘œν† νƒ€μž…κ³Ό μƒμ„±μž ν•¨μˆ˜λŠ” λ‹¨λ…μœΌλ‘œ μ‘΄μž¬ν•  수 μ—†κ³  μ–Έμ œλ‚˜ 쌍으둜 μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 단, ν΄λž˜μŠ€λŠ” 클래슀 μ •μ˜ 이전에 μ°Έμ‘°ν•  수 μ—†λ‹€.

const Perso = ''

{
  console.log(Person) // ReferenceError: Cannot access 'Person' before initialization
  
  // 클래슀 μ„ μ–Έλ¬Έ
  class Person {}
}

ν΄λž˜μŠ€λŠ” let, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ²˜λŸΌ ν˜Έμ΄μŠ€νŒ…λœλ‹€. 클래슀 μ„ μ–Έλ¬Έ 이전에 TDZ에 빠지기 λ•Œλ¬Έμ— ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.

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

ν΄λž˜μŠ€λŠ” μƒμ„±μž ν•¨μˆ˜μ΄λ©° new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœλ˜μ–΄ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€. ν΄λž˜μŠ€λŠ” new μ—°μ‚°μž 없이 ν˜ΈμΆœν•˜λ©΄ νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.



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

25.5 λ©”μ„œλ“œ

25.5.1 constructor

constructor은 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  μ΄ˆκΈ°ν™”ν•˜κΈ° μœ„ν•œ νŠΉμˆ˜ν•œ λ©”μ„œλ“œλ‹€. constructor은 이름을 λ³€κ²½ν•  수 μ—†λ‹€.

ν΄λž˜μŠ€λŠ” ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체가 λœλ‹€. ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ ν”„λ‘œν† νƒ€μž…κ³Ό μ—°κ²°λ˜μ–΄ 있으며 μžμ‹ μ˜ μŠ€μ½”ν”„μ²΄μΈμ„ κ΅¬μ„±ν•œλ‹€. λͺ¨λ“  ν•¨μˆ˜ 객체가 가지고 μžˆλŠ” prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” ν”„λ‘œν† νƒ€μž… 객체의 constructor ν”„λ‘œνΌν‹°λŠ” 클래슀 μžμ‹ μ„ 가리킀고 μžˆλ‹€.

constructor λ‚΄λΆ€μ˜ thisλŠ” μƒμ„±μž ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀.

클래슀 μ •μ˜κ°€ ν‰κ°€λ˜λ©΄ constructor의 기술된 λ™μž‘μ„ ν•˜λŠ” ν•¨μˆ˜ 객체가 μƒμ„±λœλ‹€.

constrouctor νŠΉμ§•
1. 클래슀 내에 μ΅œλŒ€ ν•œ 개만 μ‘΄μž¬ν•  수 μžˆλ‹€.
2. μƒλž΅ν•  수 μžˆλ‹€. -> 빈 constructorκ°€ μ•”λ¬΅μ μœΌλ‘œ μ •μ˜λœλ‹€.
3. μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•˜λ €λ©΄ constructorλŠ” μƒλž΅ν•˜λ©΄ μ•ˆλœλ‹€.
4. λͺ…μ‹œμ μœΌλ‘œ μ›μ‹œκ°’μ„ λ°˜ν™˜ν•˜λ©΄ μ›μ‹œκ°’ λ°˜ν™˜μ€ λ¬΄μ‹œλ˜κ³  암묡적을 thisκ°€ λ°˜ν™˜λœλ‹€.

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

클래슀 λͺΈμ²΄μ—μ„œ μ •μ˜ν•œ λ©”μ„œλ“œλŠ” 클래슀의 prototype ν”„λ‘œνΌν‹°μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜μ§€ μ•Šγ…‡λ‚˜λ„ 기본적으둜 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œκ°€ λœλ‹€.

μΈμŠ€ν„΄μŠ€λŠ” ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλ₯Ό 상속받아 μ‚¬μš©ν•  수 μžˆλ‹€.

25.5.3 정적 λ©”μ„œλ“œ

정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ ν˜ΈμΆœν•  수 μžˆλŠ” λ©”μ„œλ“œλ₯Ό λ§ν•œλ‹€. ν΄λž˜μŠ€μ—μ„œ λ©”μ„œλ“œμ— static ν‚€μ›Œλ“œλ₯Ό 뢙이면 정적 λ©”μ„œλ“œκ°€ λœλ‹€.

ν΄λž˜μŠ€λŠ” ν•¨μˆ˜ 객체둜 ν‰κ°€λ˜λ―€λ‘œ μžμ‹ μ˜ ν”„λ‘œνΌν‹°/λ©”μ„œλ“œλ₯Ό μ†Œμœ ν•  수 μžˆλ‹€. ν΄λž˜μŠ€λŠ” 클래슀 μ •μ˜κ°€ ν‰κ°€λ˜λŠ” μ‹œμ μ— ν•¨μˆ˜ 객체가 λ˜λ―€λ‘œ μΈμŠ€ν„΄μŠ€μ™€ 달리 별닀λ₯Έ 생성 과정이 ν•„μš” μ—†λ‹€. λ”°λΌμ„œ 정적 λ©”μ„œλ“œλŠ” 클래슀 μ •μ˜ 이후 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ ν˜ΈμΆœν•  수 μžˆλ‹€.

Person.sayHi() // Hi

// μΈμŠ€ν„΄μŠ€ 생성
const me = new Person('Lee')
me.sayHi() // TypeError: me.sayHi is not a function

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

  1. 정적 λ©”μ„œλ“œμ™€ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μžμ‹ μ΄ 속해 μžˆλŠ” ν”„λ‘œν† νƒ€μž… 체인이 λ‹€λ₯΄λ‹€.
  2. 정적 λ©”μ„œλ“œλŠ” 클래슀둜 ν˜ΈμΆœν•˜κ³  ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ‘œ ν˜ΈμΆœν•œλ‹€.
  3. 정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μ—†μ§€λ§Œ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.
class Square {
  // μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•˜μ§€ μ•ŠλŠ”λ‹€.
  static area(width, height) {
    return width * height
  }
}

console.log(Square.area(10, 10)) // 100

class Square {
  constructor(width, height) {
    this.width = width
    this.height = height
  }
  
  area() {
    return this.width * this.height
  }
}

const square = new Square(10, 10)
console.log(square.area()) // 100

ν”„λ‘œν† νƒ€μž…κ³Ό 정적 λ©”μ„œλ“œ λ‚΄λΆ€μ˜ this 바인딩이 λ‹€λ₯΄λ‹€. λ”°λΌμ„œ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•΄μ•Όν•  ν•„μš”κ°€ μžˆλ‹€λ©΄ thisλ₯Ό ν™œμš©ν•΄μ•Ό ν•˜λ©°, 이런 κ²½μš°λŠ” ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλ‘œ μ •μ˜ν•΄μ•Ό ν•œλ‹€. ν•˜μ§€λ§Œ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•΄μ•Ό ν•  ν•„μš”κ°€ μ—†λ‹€λ©΄ thisλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ²Œ λœλ‹€.

ν‘œμ€€ 빌트인 객체인 Math, Number, JSON, Object, Reflect 등은 λ‹€μ–‘ν•œ 정적 λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€. 이듀 정적 λ©”μ„œλ“œλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ—­μ—μ„œ μ‚¬μš©ν•  μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ‹€.

클래슀 λ˜λŠ” μƒμ„±μž ν•¨μˆ˜λ₯Ό ν•˜λ‚˜μ˜ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ μ‚¬μš©ν•˜μ—¬ 정적 λ©”μ„œλ“œλ₯Ό λͺ¨μ•„ λ†“μœΌλ©΄ 이름 좩돌 κ°€λŠ₯성을 쀄여 μ£Όκ³  κ΄€λ ¨ ν•¨μˆ˜λ“€μ„ ꡬ쑰화할 수 μžˆλŠ” νš¨κ³Όκ°€ μžˆλ‹€.

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

1. μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩

2. μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”

3. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜

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 λ‚΄λΆ€μ—μ„œ μ •μ˜ν•΄μ•Ό ν•œλ‹€. constructor λ‚΄λΆ€μ—μ„œ this에 μΆ”κ°€ν•œ ν”„λ‘œνΌν‹°λŠ” μ–Έμ œλ‚˜ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°κ°€ λœλ‹€. μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λŠ” μ–Έμ œλ‚˜ publicν•˜λ‹€.

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

μžμ²΄μ μœΌλ‘œλŠ” κ°’([[Value]])을 갖지 μ•Šκ³  λ‹€λ₯Έ 데이터 ν”„λ‘œνΌν‹°μ˜ 값을 μ½κ±°λ‚˜ μ €μž₯ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ ‘κ·Όμž ν•¨μˆ˜(getter, setter)둜 κ΅¬μ„±λœ ν”„λ‘œνΌν‹°λ‹€.

getter와 setter은 μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°μ²˜λŸΌ μ‚¬μš©λœλ‹€. ν”„λ‘œνΌν‹°μ²˜λŸΌ μ°Έμ‘°ν•˜λŠ” ν˜•μ‹μœΌλ‘œ μ‚¬μš©ν•˜λ©°, μ°Έμ‘° μ‹œμ— λ‚΄λΆ€μ μœΌλ‘œ getterλ‚˜ setterκ°€ ν˜ΈμΆœλœλ‹€.

25.7.3 클래슀 ν•„λ“œ μ •μ˜ μ œμ•ˆ

클래슀 ν•„λ“œλŠ” 클래슀 기반 객체 지ν–₯ μ–Έμ–΄μ—μ„œ ν΄λž˜μŠ€κ°€ 생성할 μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ₯Ό κ°€λ¦¬ν‚€λŠ” μš©μ–΄μ΄λ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 클래슀 λͺΈμ²΄μ—λŠ” λ©”μ„œλ“œλ§Œ μ„ μ–Έν•  수 μžˆλ‹€.

class Person {
  name = 'Lee'
}

const me = new Person('Lee')

μœ„ 예제λ₯Ό μ΅œμ‹  λΈŒλΌμš°μ €(Chrome 72 이상) λ˜λŠ” μ΅œμ‹  Node.js(버전 12 이상)μ—μ„œ μ‹€ν–‰ν•˜λ©΄ 정상 λ™μž‘ν•œλ‹€. ν•˜μ§€λ§Œ 아직 ECMAScript의 정식 ν‘œμ€€ μ‚¬μ–‘μœΌλ‘œ μŠΉκΈ‰λ˜μ§€ μ•Šμ•˜λ‹€. ν•˜μ§€λ§Œ μŠΉκΈ‰μ΄ ν™•μ‹€μ‹œ λ˜λŠ” 이 μ œμ•ˆμ„ μ„ μ œμ μœΌλ‘œ 미리 κ΅¬ν˜„ν•΄ λ†“μ•˜κΈ° λ•Œλ¬Έμ— 클래슀 ν•„λ“œλ₯Ό 클래슀 λͺΈμ²΄μ— μ •μ˜ν•  수 μžˆλŠ” 것이닀.

클래슀 ν•„λ“œμ— ν•¨μˆ˜λ₯Ό ν• λ‹Ή ν•˜λŠ” 경우 이 ν•¨μˆ˜λŠ” μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œκ°€ λœλ‹€. λͺ¨λ“  클래슀 ν•„λ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°κ°€ 되기 λ•Œλ¬Έμ΄λ‹€. 클래슀 ν•„λ“œμ— ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•˜λŠ” 것은 ꢌμž₯ν•˜μ§€ μ•ŠλŠ”λ‹€.

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

TC39 ν”„λ‘œμ„ΈμŠ€μ— stage3μ—λŠ” private ν•„λ“œλ₯Ό μ •μ˜ν•  수 μžˆλŠ” μƒˆλ‘œμš΄ ν‘œμ€€ 사양이 μ œμ•ˆλ˜μ–΄ μžˆλ‹€. 이 μ œμ•ˆλ„ μ΅œμ‹  λΆ€λΌμš°μ €μ™€ μ΅œμ‹  Node.js에 이미 κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€. private ν•„λ“œμ˜ μ„ λ‘μ—λŠ” #을 λΆ™μ—¬μ€€λ‹€.

class Person {
  #name = ''
  
  constructor(name) {
    // private ν•„λ“œ μ°Έμ‘°
    this.#name = name
  }
}

λ‹€λ§Œ private ν•„λ“œλŠ” λ°˜λ“œμ‹œ 클래슀 λͺΈμ²΄μ— μ •μ˜ν•΄μ•Ό ν•œλ‹€.

25.7.5 static ν•„λ“œ μ •μ˜ μ œμ•ˆ

static ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 정적 ν•„λ“œλ₯Ό μ •μ˜ν•  수 μžˆλ„λ‘ TC39 ν”„λ‘œμ„ΈμŠ€μ— stage3에 μ œμ•ˆλ˜μ–΄ μžˆλ‹€.

class MyMath {
  // static public ν•„λ“œ μ •μ˜
  static PI = 22 / 7
  // static private ν•„λ“œ μ •μ˜
  static #num = 10  
  // static λ©”μ„œλ“œ
  static increment() {
    return ++MyMath.#num
  }
}

console.log(MyMath.PI) // 3.142858---
console.log(MyMath.increment()) // 11

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

25.8.1 클래슀 상속과 μƒμ„±μž ν•¨μˆ˜ 상속

κΈ°μ‘΄ 클래슀λ₯Ό 상속받아 μƒˆλ‘œμš΄ 클래슀λ₯Ό ν™•μž₯ν•˜μ—¬ μ •μ˜ν•˜λŠ” 것이닀.

ν΄λž˜μŠ€λŠ” 상속을 톡해 λ‹€λ₯Έ 클래슀λ₯Ό ν™•μž₯ν•  수 μžˆλŠ” 문법인 extends ν‚€μ›Œλ“œκ°€ 기본적으둜 μ œκ³΅λœλ‹€. ν•˜μ§€λ§Œ μƒμ„±μž ν•¨μˆ˜λŠ” ν΄λž˜μŠ€μ™€ 같이 상속을 톡해 λ‹€λ₯Έ μƒμ„±μž ν•¨μˆ˜λ₯Ό ν™•μž₯ν•  수 μžˆλŠ” 문법이 μ œκ³΅λ˜μ§€ μ•ŠλŠ”λ‹€. μ˜μ‚¬ 클래슀 상속 νŒ¨ν„΄μ„ μ΄μš©ν•˜μ—¬ 흉내낼 μˆ˜λŠ” μžˆλ‹€.

25.8.2 extends ν‚€μ›Œλ“œ

// 수퍼/λΆ€λͺ¨ 클래슀
class Base {}
// μ„œλΈŒ/μžμ‹ 클래슀
class Derived extends Base {}

25.8.3 동적 상속

extends ν‚€μ›Œλ“œ λ‹€μŒμ—λŠ” 클래슀 뿐만 μ•„λ‹ˆλΌ [[Construct]] λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό κ°–λŠ” ν•¨μˆ˜ 객체둜 평가될 수 μžˆλŠ” λͺ¨λ“  ν‘œν˜„μ‹μ„ μ‚¬μš©ν•  수 μžˆλ‹€.

function Base1() {}

class Base2 {}

let condition = true

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

25.8.4 μ„œλΈŒν΄λž˜μŠ€μ˜ constructor

μ„œλΈŒ ν΄λž˜μŠ€μ—μ„œ constructor μƒλž΅ν•˜λ©΄ λ‹€μŒκ³Ό 같은 constructor μ•”λ¬΅μ μœΌλ‘œ μ •μ˜λœλ‹€. argsλŠ” new μ—°μ‚°μžμ™€ ν•¨κ»˜ 클래슀λ₯Ό ν˜ΈμΆœν•  λ•Œ μ „λ‹¬ν•œ 인수 λ¦¬μŠ€νŠΈλ‹€.

super()λŠ” 수퍼클래슀의 constructorλ₯Ό ν˜ΈμΆœν•˜μ—¬ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.

class Base {
  constructor() {}
}

class Derived extends Base {
  // λ‹€μŒκ³Ό 같이 μ•”λ¬΅μ μœΌλ‘œ constructorκ°€ μ •μ˜λœλ‹€.
  constructor(...args) { 
     super(...args)
  }
}

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

25.9.5 super ν‚€μ›Œλ“œ

super ν‚€μ›Œλ“œλŠ” ν•¨μˆ˜μ²˜λŸΌ ν˜ΈμΆœν•  μˆ˜λ„ 있고 this와 같이 μ‹λ³„μžμ²˜λŸΌ μ°Έμ‘°ν•  수 μžˆλ‹€.

super 호좜

superλ₯Ό ν˜ΈμΆœν•˜λ©΄ 수퍼클래슀의 constructorλ₯Ό ν˜ΈμΆœν•œλ‹€.

λ‹€μŒ μ˜ˆμ œμ™Έ 같이 μˆ˜νΌν΄λž˜μŠ€μ—μ„œ μΆ”κ°€ν•œ ν”„λ‘œνΌν‹°μ™€ μ„œλΈŒν΄λž˜μŠ€μ—μ„œ μΆ”κ°€ν•œ ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€λ©΄ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorλ₯Ό μƒλž΅ν•  수 μ—†λ‹€.

class Base {
  constructor(a, b) { // 2) 1μ—μ„œ ν˜ΈμΆœν•œ 인수λ₯Ό 전달 λ°›μŒ
    this.a = a
    this.b = b
  }
}

class Derived extends Base {
  constructor(a, b, c) {
    super(a, b) // 1) super호좜둜 Base 클래슀둜 보냄
    this.c = c
  }
}

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

super 호좜 μ‹œ μ£Όμ˜μ‚¬ν•­
1. μ„œλΈŒν΄λž˜μŠ€μ—μ„œ constructorλ₯Ό μƒλž΅ν•˜μ§€ μ•ŠλŠ” 경우 μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œλŠ” λ°˜λ“œμ‹œ superλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.

class Base {}

class Derived extends Base {
  constructor() {
  	// ReferenceError
  }
}
  
  1. μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜κΈ° μ „μ—λŠ” thisλ₯Ό μ°Έμ‘°ν•  수 μ—†λ‹€.
class Base {}

class Derived extends Base {
  constructor() {
  	// ReferenceError
    this.a = 1
    super()
  }
}
  1. superλŠ” λ°˜λ“œμ‹œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œλ§Œ ν˜ΈμΆœν•œλ‹€.

super μ°Έμ‘°

super을 μ°Έμ‘°ν•˜λ©΄ 수퍼클래슀의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

  1. μ„œλΈŒν΄λž˜μŠ€μ˜ ν”„λ‘œν† ν‹°μž… λ©”μ„œλ“œ λ‚΄μ—μ„œ super.sayHiλŠ” 수퍼클래슀의 ν”„λ‘œν„°νƒ€μž… λ©”μ„œλ“œ sayHiλ₯Ό 가리킨닀.

  2. μ„œλΈŒν΄λž˜μŠ€μ˜ 정적 λ©”μ„œλ“œ λ‚΄μ—μ„œ super.sayHiλŠ” 수퍼클래슀의 정적 λ©”μ„œλ“œ sayHiλ₯Ό 가리킨닀.

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

1. μ„œλΈŒ 클래슀의 super 호좜

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 클래슀λ₯Ό 평가할 λ•Œ μˆ˜νΌν΄λž˜μŠ€μ™€ μ„œλΈŒν΄λž˜μŠ€λ₯Ό κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ 'base' λ˜λŠ” 'derived'λ₯Ό κ°’μœΌλ‘œ κ°–λŠ” λ‚΄λΆ€ 슬둯 [[ConstructorKind]]λ₯Ό κ°–λŠ”λ‹€.

μ„œλΈŒν΄λž˜μŠ€λŠ” μžμ‹ μ΄ 직접 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  μˆ˜νΌν΄λž˜μŠ€μ—κ²Œ μΈμŠ€ν„΄μŠ€ 생성을 μœ„μž„ν•œλ‹€. 이것이 λ°”λ‘œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ super을 ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” μ΄μœ λ‹€.

2. 수퍼클래슀의 μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩

수퍼클래슀의 consturctor λ‚΄λΆ€μ˜ μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° 이전에 μ•”λ¬΅μ μœΌλ‘œ 빈 객체λ₯Ό μƒμ„±ν•œλ‹€. 이 빈 객체가 λ°”λ‘œ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€μ΄λ‹€. μ΄λ•Œ μΈμŠ€ν„΄μŠ€λŠ” μˆ˜νΌν΄λž˜μŠ€κ°€ μƒμ„±ν•œ 것이닀. ν•˜μ§€λ§Œ new μ—°μ‚°μžμ™€ ν•¨κ»˜ 호좜된 ν΄λž˜μŠ€κ°€ μ„œλΈŒν΄λž˜μŠ€ λΌλŠ” 것이 μ€‘μš”ν•˜λ‹€. μΈμŠ€ν„΄μŠ€λŠ” new.target이 κ°€λ¦¬ν‚€λŠ” μ„œλΈŒν΄λž˜μŠ€κ°€ μƒμ„±ν•œ κ²ƒμœΌλ‘œ μ²˜λ¦¬λœλ‹€.

3. 수퍼클래슀의 μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”

수퍼클래슀의 constructorκ°€ μ‹€ν–‰λ˜μ–΄ this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

4. μ„œλΈŒν΄λž˜μŠ€ constructor둜의 볡귀와 this 바인딩

super 호좜이 μ’…λ£Œλ˜κ³  μ œμ–΄ 흐름이 μ„œλΈŒν΄λž˜μŠ€ constructor둜 λŒμ•„μ˜¨λ‹€. μ΄λ•Œ super이 λ°˜ν™˜ν•œ μΈμŠ€ν„΄μŠ€κ°€ this에 λ°”μΈλ”©λœλ‹€.

5. μ„œλΈŒν΄λž˜μŠ€ μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”

super 호좜 이후, μ„œλΈŒν΄λž˜μŠ€μ˜ constructor에 κΈ°μˆ λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”κ°€ μ‹€ν–‰λœλ‹€.

6. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜

클래슀의 λͺ¨λ“  μ²˜λ¦¬κ°€ λλ‚˜λ©΄ μ™„μ„±λœ μΈμŠ€ν„΄μŠ€κ°€ λ°”μΈλ”©λœ thisκ°€ μ•”λ¬΅μ μœΌλ‘œ λ°˜ν™˜λœλ‹€.

Ref

  • 이웅λͺ¨ μ €, ⌜λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive⌟, μœ„ν‚€λΆμŠ€
profile
맀 μˆœκ°„ μ„±μž₯ν•˜λŠ” κ°œλ°œμžκ°€ 되렀고 λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€