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

ES6μ—μ„œ λ„μž…λœ ν΄λž˜μŠ€λŠ” κΈ°μ‘΄ ν”„λ‘œν† νƒ€μž… 기반의 νŒ¨ν„΄μ„ 클래슀 기반 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ— μ΅μˆ™ν•΄μ§€κΈ° 쉽도둝 μƒˆλ‘œμš΄ 객체 생성 λ©”μ»€λ‹ˆμ¦˜μ„ μ œμ‹œν•œλ‹€.

κΈ°μ‘΄ ν”„λ‘œν† νƒ€μž… 기반 객체지ν–₯ λͺ¨λΈμ„ νμ§€ν•˜κ³  μƒˆλ‘­κ²Œ 클래슀 기반 객체지ν–₯λͺ¨λΈμ„ μ œκ³΅ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. ν΄λž˜μŠ€λŠ” μƒμ„±μž ν•¨μˆ˜μ™€ 맀우 μœ μ‚¬ν•˜κ²Œ λ™μž‘ν•˜μ§€λ§Œ λ‹€μŒ λͺ‡ 가지 차이가 μžˆλ‹€.

  1. 클래슀λ₯Ό new μ—°μ‚°μž 없이 ν˜ΈμΆœν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. ν•˜μ§€λ§Œ μƒμ„±μž ν•¨μˆ˜λ₯Ό new μ—°μ‚°μž 없이 ν˜ΈμΆœν•˜λ©΄ 일반 ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœλœλ‹€.
  2. ν΄λž˜μŠ€λŠ” 상속을 μ§€μ›ν•˜λŠ” extends와 super ν‚€μ›Œλ“œλ₯Ό μ œκ³΅ν•œλ‹€. ν•˜μ§€λ§Œ μƒμ„±μž ν•¨μˆ˜λŠ” extends와 super ν‚€μ›Œλ“œλ₯Ό μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.
  3. ν΄λž˜μŠ€λŠ” ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜ μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜λœ μƒμ„±μž ν•¨μˆ˜λŠ” ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄, ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ μ •μ˜ν•œ μƒμ„±μž ν•¨μˆ˜λŠ” λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•œλ‹€.
  4. 클래슀 λ‚΄μ˜ λͺ¨λ“  μ½”λ“œμ—λŠ” μ•”λ¬΅μ μœΌλ‘œ strict modeκ°€ μ§€μ •λ˜μ–΄ μ‹€ν–‰λ˜λ©° strict modeλ₯Ό ν•΄μ œν•  수 μ—†λ‹€. ν•˜μ§€λ§Œ μƒμ„±μž ν•¨μˆ˜λŠ” μ•”λ¬΅μ μœΌλ‘œ strict modeκ°€ μ§€μ •λ˜μ§€ μ•ŠλŠ”λ‹€.
  5. 클래슀의 constructor, ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ, 정적 λ©”μ„œλ“œλŠ” λͺ¨λ‘ ν”„λ‘œνΌν‹° μ–΄νŠΈλ¦¬λ·°νŠΈ [[Enumerable]]의 값이 falseλ‹€. λ‹€μ‹œ 말해, μ—΄κ±°λ˜μ§€ μ•ŠλŠ”λ‹€.

πŸ“Œ 25.2 클래슀 μ •μ˜

ν΄λž˜μŠ€λŠ” class ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ •μ˜ν•˜λ©° 클래슀 이름은 μƒμ„±μž ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 파슀칼 μΌ€μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.

// 클래슀 μ„ μ–Έλ¬Έ
class Person {}

ν΄λž˜μŠ€λŠ” 일급 κ°μ²΄λ‘œμ„œ λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ κ°–λŠ”λ‹€.

  • 무λͺ…μ˜ λ¦¬ν„°λŸ΄λ‘œ 생성할 수 μžˆλ‹€. 즉, λŸ°νƒ€μž„μ— 생성이 κ°€λŠ₯ν•˜λ‹€.
  • λ³€μˆ˜λ‚˜ 자료ꡬ쑰(객체, λ°°μ—΄ λ“±)에 μ €μž₯ν•  수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ—κ²Œ 전달할 수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.


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

ν΄λž˜μŠ€λŠ” ν•¨μˆ˜λ‘œ ν‰κ°€λ˜κΈ° λ•Œλ¬Έμ— λŸ°νƒ€μž„ 이전에 λ¨Όμ € ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체λ₯Ό μƒμ„±ν•œλ‹€. μ΄λ•Œ ν΄λž˜μŠ€κ°€ ν‰κ°€λ˜μ–΄ μƒμ„±λœ ν•¨μˆ˜ κ°μ²΄λŠ” μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  수 μžˆλŠ” ν•¨μˆ˜, 즉 constructor 이닀. μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•  수 μžˆλŠ” ν•¨μˆ˜λŠ” ν•¨μˆ˜ μ •μ˜κ°€ ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체λ₯Ό μƒμ„±ν•˜λŠ” μ‹œμ μ— ν”„λ‘œν† νƒ€μž…λ„ λ”λΆˆμ–΄ μƒμ„±λœλ‹€.

const Person = '';

{
  // ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ ''이 좜λ ₯λ˜μ–΄μ•Ό ν•œλ‹€.
  console.log(Person);
  // ReferenceError: Cannot access 'Person' before initialization

  // 클래슀 μ„ μ–Έλ¬Έ
  class Person {}
}

클래슀 선언문도 λ³€μˆ˜ μ„ μ–Έ, ν•¨μˆ˜ μ •μ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•œλ‹€. 단, ν΄λž˜μŠ€λŠ” let, const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜μ²˜λŸΌ ν˜Έμ΄μŠ€νŒ… λ˜μ–΄ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”κ°€ λΆ„λ¦¬λ˜μ–΄ μ§„ν–‰λ˜κΈ° λ•Œλ¬Έμ— TDZ(μΌμ‹œμ  μ‚¬κ°μ§€λŒ€)에 λΉ μ§€κ²Œ λ˜μ–΄ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.

πŸ“Œ 25.4 μΈμŠ€ν„΄μŠ€ 생성

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

ν•¨μˆ˜λŠ” new μ—°μ‚°μžμ˜ μ‚¬μš© 여뢀에 따라 일반 ν•¨μˆ˜λ‘œ ν˜ΈμΆœλ˜κ±°λ‚˜ μΈμŠ€ν„΄μŠ€ 생성을 μœ„ν•œ μƒμ„±μž ν•¨μˆ˜λ‘œ ν˜ΈμΆœλ˜μ§€λ§Œ ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 것이 μœ μΌν•œ 쑴재 μ΄μœ μ΄λ―€λ‘œ λ°˜λ“œμ‹œ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.

class Person {}

// μΈμŠ€ν„΄μŠ€ 생성
const me = new Person();
console.log(me); // Person {}

// 클래슀λ₯Ό new μ—°μ‚°μž 없이 ν˜ΈμΆœν•˜λ©΄ νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
const you = Person();
// TypeError: Class constructor Foo cannot be invoked without 'new'

πŸ“Œ 25.5 λ©”μ„œλ“œ

클래슀 λͺΈμ²΄μ—λŠ” 0개 μ΄μƒμ˜ λ©”μ„œλ“œλ§Œ μ„ μ–Έν•  수 μžˆλ‹€.
클래슀 λͺΈμ²΄μ—μ„œ μ •μ˜ν•  수 μžˆλŠ” λ©”μ„œλ“œλŠ” constructor(μƒμ„±μž), ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ, 정적 λ©”μ„œλ“œ 세가지가 μžˆλ‹€.

βœ” 25.5.1 constructor

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

class Person {
  // μƒμ„±μž
  constructor(name) {
    // μΈμŠ€ν„΄μŠ€ 생성 및 μ΄ˆκΈ°ν™”
    this.name = name;
  }
}

constructor(ν”„λ‘œν† νƒ€μž…μ˜ constuctor ν”„λ‘œνΌν‹°μ™€ 닀름)λŠ” λ©”μ„œλ“œλ‘œ ν•΄μ„λ˜λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ ν΄λž˜μŠ€κ°€ ν‰κ°€λ˜μ–΄ μƒμ„±ν•œ ν•¨μˆ˜ 객체 μ½”λ“œμ˜ 일뢀가 λœλ‹€. 즉, 클래슀 μ •μ˜κ°€ ν‰κ°€λ˜λ©΄ constructor의 기술된 λ™μž‘μ„ ν•˜λŠ” ν•¨μˆ˜ 객체가 μƒμ„±λœλ‹€.

consturctorλŠ” λ³„λ„μ˜ λ°˜ν™˜λ¬Έμ„ 갖지 μ•Šμ•„μ•Ό ν•œλ‹€. 17.2.3μ ˆμ—μ„œ β€œμƒμ„±μž ν•¨μˆ˜μ˜ μΈμŠ€ν„΄μŠ€ 생성 κ³Όμ •β€μ—μ„œ μ‚΄νŽ΄λ³΄μ•˜λ“―μ΄ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν΄λž˜μŠ€κ°€ 호좜되면 μƒμ„±μž ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ μ•”λ¬΅μ μœΌλ‘œ this, 즉 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— thisκ°€ μ•„λ‹Œ λ‹€λ₯Έ 객체λ₯Ό λͺ…μ‹œμ μœΌλ‘œ λ°˜ν™˜ν•˜λ©΄ 클래슀의 κΈ°λ³Έλ™μž‘μ„ ν›Όμ†ν•œλ‹€.

βœ” 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

// me 객체의 ν”„λ‘œν† νƒ€μž…μ€ Person.prototype이닀.
Object.getPrototypeOf(me) === Person.prototype; // -> true
me instanceof Person; // -> true

// Person.prototype의 ν”„λ‘œν† νƒ€μž…μ€ Object.prototype이닀.
Object.getPrototypeOf(Person.prototype) === Object.prototype; // -> true
me instanceof Object; // -> true

// me 객체의 constructorλŠ” Person ν΄λž˜μŠ€λ‹€.
me.constructor === Person; // -> true

즉 ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λŠ” ν”„λ‘œν† νƒ€μž… 체인의 일원이 λ˜μ–΄ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλ₯Ό 상속받아 μ‚¬μš©ν• μˆ˜ μžˆλ‹€.

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

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

class Person {
  // μƒμ„±μž
  constructor(name) {
    // μΈμŠ€ν„΄μŠ€ 생성 및 μ΄ˆκΈ°ν™”
    this.name = name;
  }

  // 정적 λ©”μ„œλ“œ
  static sayHi() {
    console.log('Hi!');
  }
}
// 정적 λ©”μ„œλ“œλŠ” 클래슀둜 ν˜ΈμΆœν•œλ‹€.
// 정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ 없이도 ν˜ΈμΆœν•  수 μžˆλ‹€.
Person.sayHi(); // Hi!

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

정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ‘œ ν˜ΈμΆœν• μˆ˜ μ—†κ³  클래슀둜 ν˜ΈμΆœν•œλ‹€. 정적 λ©”μ„œλ“œκ°€ 바인딩 된 ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž… 체인상에 μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

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

  1. 정적 λ©”μ„œλ“œμ™€ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μžμ‹ μ΄ 속해 μžˆλŠ” ν”„λ‘œν† νƒ€μž… 체인이 λ‹€λ₯΄λ‹€.
  2. 정적 λ©”μ„œλ“œλŠ” 클래슀둜 ν˜ΈμΆœν•˜κ³  ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€λ‘œ ν˜ΈμΆœν•œλ‹€.
  3. 정적 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μ—†μ§€λ§Œ ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.

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

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

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

  1. μΈμŠ€ν„΄μŠ€ 생성과 this 바인딩
  2. μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”
  3. μΈμŠ€ν„΄μŠ€ λ°˜ν™˜

πŸ“Œ 25.7 ν”„λ‘œνΌν‹°

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

μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λŠ” constructor λ‚΄λΆ€μ—μ„œ μ •μ˜ν•΄μ•Ό ν•œλ‹€. constructor λ‚΄λΆ€μ—μ„œ this에 μΆ”κ°€ν•œ ν”„λ‘œνΌν‹°λŠ” μ–Έμ œλ‚˜ ν΄λž˜μŠ€κ°€ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°κ°€ λœλ‹€.

class Person {
  constructor(name) {
    // μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°
    this.name = name;
  }
}

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

class Person {
  constructor(name) {
    // μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°
    this.name = name; // name ν”„λ‘œνΌν‹°λŠ” publicν•˜λ‹€.
  }
}

const me = new Person('Lee');

// name은 publicν•˜λ‹€.
console.log(me.name); // Lee

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

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

getterλŠ” 이름 κ·ΈλŒ€λ‘œ 무언가λ₯Ό 취득할 λ•Œ μ‚¬μš©ν•˜λ―€λ‘œ λ°˜λ“œμ‹œ 무언가λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•˜κ³  setterλŠ” 무언가λ₯Ό ν”„λ‘œνΌν‹°μ— ν• λ‹Ή ν•΄μ•Όν•  λ•Œ μ‚¬μš©ν•˜λ―€λ‘œ λ°˜λ“œμ‹œ λ§€κ°œλ³€μˆ˜κ°€ μžˆμ–΄μ•Ό ν•œλ‹€. setterλŠ” 단 ν•˜λ‚˜μ˜ κ°’λ§Œ ν• λ‹Ήλ°›κΈ° λ•Œλ¬Έμ— 단 ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜λ§Œ μ„ μ–Έν•  수 μžˆλ‹€.

클래슀의 λ©”μ„œλ“œλŠ” 기본적으둜 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œκ°€ λœλ‹€. λ”°λΌμ„œ 클래슀의 μ ‘κ·Όμž ν”„λ‘œνΌν‹° λ˜ν•œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°κ°€ μ•„λ‹Œ ν”„λ‘œν† νƒ€μž…μ˜ ν”„λ‘œνΌν‹°κ°€ λœλ‹€.

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

클래슀 ν•„λ“œλž€ 클래슀 기반 객체지ν–₯ μ–Έμ–΄μ—μ„œ ν΄λž˜μŠ€κ°€ 생성할 μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ₯Ό κ°€λ¦¬ν‚€λŠ” μš©μ–΄λ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλ„ μƒˆλ‘œμš΄ ν‘œμ€€ 사양인 β€œClass field declarations”가 μ œμ•ˆλ˜μ—ˆλ‹€. 이둜 인해 μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•˜λŠ” 방식은 두 가지가 λ˜μ—ˆλ‹€.

μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μ™ΈλΆ€ μ΄ˆκΈ°κ°’μœΌλ‘œ 클래슀 ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•  ν•„μš”κ°€ μžˆλ‹€λ©΄ constuctorμ—μ„œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•˜λŠ” 기쑴방식을 μ‚¬μš©ν•˜κ³ , μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μ™ΈλΆ€ μ΄ˆκΈ°κ°’μœΌλ‘œ ν΄λž˜μŠ€ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•  ν•„μš”κ°€ μ—†λ‹€λ©΄ 기쑴의 constructorμ—μ„œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•˜λŠ” 방식과 클래슀 ν•„λ“œ μ •μ˜ μ œμ•ˆ λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆλ‹€.

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

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλ„ private ν•„λ“œλ₯Ό μ •μ˜ν•  수 μžˆλŠ” μƒˆλ‘œμš΄ ν‘œμ€€ 사양이 μ œμ•ˆλ˜μ–΄ μžˆλ‹€. private ν•„λ“œμ˜ μ„ λ‘μ—λŠ” #을 λΆ™μ—¬μ€€λ‹€. private ν•„λ“œλ₯Ό μ°Έμ‘°ν•  λ•Œλ„ #을 λΆ™μ—¬μ£Όμ–΄μ•Ό ν•œλ‹€. private ν•„λ“œλŠ” 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆλ‹€. λ˜ν•œ, private ν•„λ“œλŠ” λ°˜λ“œμ‹œ 클래슀 λͺΈμ²΄μ— μ •μ˜ν•΄μ•Ό ν•œλ‹€.

class Person {
  // private ν•„λ“œ μ •μ˜
  #name = '';

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

const me = new Person('Lee');

// private ν•„λ“œ #name은 클래슀 μ™ΈλΆ€μ—μ„œ μ°Έμ‘°ν•  수 μ—†λ‹€.
console.log(me.#name);
// SyntaxError: Private field '#name' must be declared in an enclosing class

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

static publicν•„λ“œ, static private ν•„λ“œ, sstatic private λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μž‡λŠ” μƒˆλ‘œμš΄ ν‘œμ€€ 사양인 β€œStatic class features”가 μ œμ•ˆλ˜μ–΄ μžˆλ‹€.

class MyMath {
  // static public ν•„λ“œ μ •μ˜
  static PI = 22 / 7;

  // static private ν•„λ“œ μ •μ˜
  static #num = 10;

  // static λ©”μ„œλ“œ
  static increment() {
    return ++MyMath.#num;
  }
}

console.log(MyMath.PI); // 3.142857142857143
console.log(MyMath.increment()); // 11

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

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

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

βœ” 25.8.2 extends ν‚€μ›Œλ“œ

extends ν‚€μ›Œλ“œμ˜ 역할은 μˆ˜νΌν΄λž˜μŠ€μ™€ μ„œλΈŒν΄λž˜μŠ€ κ°„μ˜ 상속 관계λ₯Ό μ„€μ •ν•˜λŠ” 것이닀. 상속을 톡해 ν™•μž₯된 클래슀λ₯Ό μ„œλΈŒν΄λž˜μŠ€λΌ λΆ€λ₯΄κ³ , μ„œλΈŒν΄λž˜μŠ€μ—κ²Œ μƒμ†λœ 클래슀λ₯Ό 수퍼클래슀라고 λΆ€λ₯Έλ‹€.λŠ”

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

// μ„œλΈŒ(νŒŒμƒ/μžμ‹)클래슀
class Derived extends Base {}

μˆ˜νΌν΄λž˜μŠ€μ™€ μ„œλΈŒν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž… 체인뿐 μ•„λ‹ˆλΌ 클래슀 κ°„μ˜ ν”„λ‘œν† νƒ€μž… 체인도 μƒμ„±ν•œλ‹€. 이λ₯Ό 톡해 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ, 정적 λ©”μ„œλ“œ λͺ¨λ‘ 상속이 κ°€λŠ₯ν•˜λ‹€.

βœ” 25.8.3 동적 상속

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

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

βœ” 25.8.4 μ„œλΈŒ 클래슀의 constructor

μˆ˜νΌν΄λž˜μŠ€μ—μ„œ consturctorλ₯Ό μƒλž΅ν•˜λ©΄ 빈 객체가 μƒμ„±λœλ‹€. μ„œλΈŒν΄λž˜μŠ€ λ§ˆμ°¬κ°€μ§€λ‘œ constructorλ₯Ό μƒλž΅ν•˜λ©΄ ν΄λž˜μŠ€μ— λ‹€μŒκ³Ό 같은 constructorκ°€ μ•”λ¬΅μ μœΌλ‘œ μ •μ˜λœλ‹€.

constructor(...args) { super(...args); }

βœ” 25.8.5 super ν‚€μ›Œλ“œ

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

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

      class Base {}
      
      class Derived extends Base {
        constructor() {
          // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
          console.log('constructor call');
        }
      }
      
      const derived = new Derived();
    2. μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜κΈ° μ „μ—λŠ” thisλ₯Ό μ°Έμ‘°ν• μˆ˜ μ—†λ‹€.

      class Base {}
      
      class Derived extends Base {
        constructor() {
          // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
          this.a = 1;
          super();
        }
      }
      
      const derived = new Derived(1);
    3. superλŠ” λ°˜λ“œμ‹œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œλ§Œ ν˜ΈμΆœν•œλ‹€. μ„œλΈŒν΄λž˜μŠ€κ°€ μ•„λ‹Œ 클래슀의 constructorλ‚˜ ν•¨μˆ˜μ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

      class Base {
        constructor() {
          super(); // SyntaxError: 'super' keyword unexpected here
        }
      }
      
      function Foo() {
        super(); // SyntaxError: 'super' keyword unexpected here
      }
  • super μ°Έμ‘° λ©”μ„œλ“œ λ‚΄μ—μ„œ superλ₯Ό μ°Έμ‘°ν•˜λ©΄ 수퍼클래슀의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.
    1. μ„œλΈŒ 클래슀의 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ λ‚΄μ—μ„œ super.sayHiλŠ” 수퍼클래슀의 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œ sayHiλ₯Ό 가리킨닀.

      // 수퍼클래슀
      class Base {
        constructor(name) {
          this.name = name;
        }
      
        sayHi() {
          return `Hi! ${this.name}`;
        }
      }
      
      // μ„œλΈŒν΄λž˜μŠ€
      class Derived extends Base {
        sayHi() {
          // super.sayHiλŠ” 수퍼클래슀의 ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλ₯Ό 가리킨닀.
          return `${super.sayHi()}. how are you doing?`;
        }
      }
      
      const derived = new Derived('Lee');
      console.log(derived.sayHi()); // Hi! Lee. how are you doing?
    2. μ„œλΈŒν΄λž˜μŠ€μ˜ 정적 λ©”μ„œλ“œ λ‚΄μ—μ„œ super.sayHiλŠ” 수퍼클래슀의 정적 λ©”μ„œλ“œ sayHiλ₯Ό 가리킨닀.

      // 수퍼클래슀
      class Base {
        static sayHi() {
          return 'Hi!';
        }
      }
      
      // μ„œλΈŒν΄λž˜μŠ€
      class Derived extends Base {
        static sayHi() {
          // super.sayHiλŠ” 수퍼클래슀의 정적 λ©”μ„œλ“œλ₯Ό 가리킨닀.
          return `${super.sayHi()} how are you doing?`;
        }
      }
      
      console.log(Derived.sayHi()); // Hi! how are you doing?

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

μ„œλΈŒν΄λž˜μŠ€μ˜ ColorRectangle이 new μ—°μ‚°μžμ™€ ν•¨κ»˜ 호좜되면 λ‹€μŒ 과정을 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.

// 수퍼클래슀
class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }

  toString() {
    return `width = ${this.width}, height = ${this.height}`;
  }
}

// μ„œλΈŒν΄λž˜μŠ€
class ColorRectangle extends Rectangle {
  constructor(width, height, color) {
    super(width, height);
    this.color = color;
  }

  // λ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ”©
  toString() {
    return super.toString() + `, color = ${this.color}`;
  }
}

const colorRectangle = new ColorRectangle(2, 4, 'red');
console.log(colorRectangle); // ColorRectangle {width: 2, height: 4, color: "red"}

// 상속을 톡해 getArea λ©”μ„œλ“œλ₯Ό 호좜
console.log(colorRectangle.getArea()); // 8
// μ˜€λ²„λΌμ΄λ”©λœ toString λ©”μ„œλ“œλ₯Ό 호좜
console.log(colorRectangle.toString()); // width = 2, height = 4, color = red
  1. μ„œλΈŒν΄λž˜μŠ€μ˜ super 호좜

    λ‹€λ₯Έ 클래슀λ₯Ό 상속받지 μ•ŠλŠ” 클래슀(그리고 μƒμ„±μž ν•¨μˆ˜)λŠ” new μ—°μ‚°μžκ°€ ν•¨κ»˜ ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ μ•”λ¬΅μ μœΌλ‘œ 빈 객체, 즉 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  이λ₯Ό this에 λ°”μΈλ”©ν•œλ‹€. ν•˜μ§€λ§Œ μ„œλΈŒν΄λž˜μŠ€λŠ” μžμ‹ μ΄ 직접 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  μˆ˜νΌν΄λž˜μŠ€μ—κ²Œ μΈμŠ€ν„΄μŠ€ 생성을 μœ„μž„ν•œλ‹€. 이것이 λ°”λ‘œ μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ λ°˜λ“œμ‹œ superλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” μ΄μœ λ‹€.

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

    수퍼클래슀 constructor의 λ‚΄λΆ€μ˜ thisλŠ” μƒμ„±λœ μΈμŠ€ν„΄μŠ€(빈 객체)λ₯Ό 가리킨닀. 이 λ•Œ μΈμŠ€ν„΄μŠ€λŠ” new.target이 κ°€λ¦¬ν‚€λŠ” μ„œλΈŒν΄λž˜μŠ€κ°€ μƒμ„±ν•œ κ²ƒμœΌλ‘œ μ²˜λ¦¬λœλ‹€. λ”°λΌμ„œ μƒμ„±λœ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž…μ€ 수퍼클래슀의 prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” 객체(Rectangle.prototype)κ°€ μ•„λ‹ˆλΌ new.target, 즉 μ„œλΈŒν΄λž˜μŠ€μ˜ prototype ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” 객체(ColorRectangle.prototype)이닀.

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

    수퍼클래슀의 constructorκ°€ μ‹€ν–‰λ˜μ–΄ this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€. 즉, this에 바인딩 λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€μ— ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•˜κ³  constructorκ°€ 인수둜 전달받은 μ΄ˆκΈ°κ°’μœΌλ‘œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

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

    super의 호좜의 μ’…λ£Œλ˜κ³  μ œμ–΄ 프름이 μ„œλΈŒν΄λž˜μŠ€ constructor둜 λŒμ•„μ˜¨λ‹€. μ΄λ•Œ superκ°€ λ°˜ν™˜ν•œ μΈμŠ€ν„΄μŠ€κ°€ this에 λ°”μΈλ”©λœλ‹€. μ„œλΈŒν΄λž˜μŠ€λŠ” λ³„λ„μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  superκ°€ λ°˜ν™˜ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό this에 λ°”μΈλ”©ν•˜μ—¬ κ·ΈλŒ€λ‘œ μ‚¬μš©ν•œλ‹€. 이처럼 superκ°€ ν˜ΈμΆœλ˜μ§€ μ•ŠμœΌλ©΄ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜μ§€ μ•ŠμœΌλ©°, this 바인딩도 ν• μˆ˜ μ—†λ‹€. μ„œλΈŒν΄λž˜μŠ€μ˜ constructorμ—μ„œ superλ₯Ό ν˜ΈμΆœν•˜κΈ° μ „μ—λŠ”thisλ₯Ό μ°Έμ‘°ν•  수 μ—†λŠ” μ΄μœ κ°€ λ°”λ‘œ 이 λ•Œλ¬Έμ΄λ‹€.

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

    super 호좜 이후, μ„œλΈŒν΄λž˜μŠ€μ˜ consstructor에 κΈ°μˆ λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™”κ°€ μ‹€ν–‰λœλ‹€. 즉, this에 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€μ— ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•˜κ³  constructorκ°€ 인수둜 전달받은 μ΄ˆκΈ°κ°’μœΌλ‘œ μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€.

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

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

βœ” 25.8.7 ν‘œμ€€ 빌트인 μƒμ„±μž ν•¨μˆ˜ ν™•μž₯

ν‘œμ€€λΉŒνŠΈμΈ 객체 λ˜ν•œ [[Construct]] λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό κ°–λŠ” μƒμ„±μž ν•¨μˆ˜μ΄λ―€λ‘œ extends ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ν™•μž₯ν•  수 μžˆλ‹€.

profile
μ΄μ‚¬μ€‘μž…λ‹ˆλ‹€!🌟https://velog.io/@devkyoung2

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보