Skip to content

Latest commit

Β 

History

History
764 lines (561 loc) Β· 36.1 KB

File metadata and controls

764 lines (561 loc) Β· 36.1 KB

객체 μƒμ„±ν•˜λŠ” λ‹€μ–‘ν•œ 방법

생성 방법 문법 μ„€λͺ… νŠΉμ§• μ˜ˆμ‹œ
객체 λ¦¬ν„°λŸ΄ {} μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•˜μ—¬ 직접 객체λ₯Ό 생성 κ°€μž₯ κ°„λ‹¨ν•˜κ³  일반적인 방법 const person = { name: '홍길동', age: 30 };
μƒμ„±μž ν•¨μˆ˜ new Constructor() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 객체 ν…œν”Œλ¦Ώ μ •μ˜ μ—¬λŸ¬ μœ μ‚¬ν•œ 객체λ₯Ό λ§Œλ“€ λ•Œ 유용 function Person(name, age) { this.name = name; this.age = age; } const person = new Person('홍길동', 30);
Object μƒμ„±μž new Object() Object λ‚΄μž₯ μƒμ„±μž μ‚¬μš© λ¦¬ν„°λŸ΄λ³΄λ‹€ 덜 μ‚¬μš©λ¨ const person = new Object(); person.name = '홍길동'; person.age = 30;
Object.create() Object.create(proto) μ§€μ •λœ ν”„λ‘œν† νƒ€μž… 객체와 속성을 κ°–λŠ” μƒˆ 객체 생성 ν”„λ‘œν† νƒ€μž… 상속을 λͺ…μ‹œμ μœΌλ‘œ μ§€μ • const personProto = { greet() { return μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€; } }; const person = Object.create(personProto); person.name = '홍길동';
클래슀 (ES6+) class ... {} 클래슀 λ¬Έλ²•μœΌλ‘œ 객체 ν…œν”Œλ¦Ώ μ •μ˜ μƒμ„±μž ν•¨μˆ˜μ˜ 문법적 섀탕, OOP μŠ€νƒ€μΌ class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { return μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€; } } const person = new Person('홍길동', 30);
νŒ©ν† λ¦¬ ν•¨μˆ˜ factory() 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 일반 ν•¨μˆ˜ new ν‚€μ›Œλ“œ 없이 객체 생성 κ°€λŠ₯ function createPerson(name, age) { return { name, age, greet() { return μ•ˆλ…•ν•˜μ„Έμš”, ${name}μž…λ‹ˆλ‹€; } }; } const person = createPerson('홍길동', 30);
Object.assign() Object.assign({}, obj) ν•˜λ‚˜ μ΄μƒμ˜ 원본 κ°μ²΄μ—μ„œ λŒ€μƒ 객체둜 속성 볡사 객체 λ³΅μ œλ‚˜ 합성에 유용 const defaults = { age: 0, gender: 'λ―Έμ§€μ •' }; const person = Object.assign({}, defaults, { name: '홍길동', age: 30 });
객체 λΆ„ν•΄ ν• λ‹Ή (ES6+) {...obj} μŠ€ν”„λ ˆλ“œ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ—¬ 객체 속성 볡사 κ°„κ²°ν•œ ꡬ문으둜 객체 볡제 const defaults = { age: 0, gender: 'λ―Έμ§€μ •' }; const person = { ...defaults, name: '홍길동', age: 30 };
Map 객체 (ES6+) new Map() ν‚€-κ°’ μŒμ„ μ €μž₯ν•˜λŠ” μ»¬λ ‰μ…˜ ν‚€κ°€ λ¬Έμžμ—΄μ΄ μ•„λ‹Œ 값도 κ°€λŠ₯ const person = new Map(); person.set('name', '홍길동'); person.set('age', 30);
Proxy (ES6+) new Proxy(obj, handler) 객체의 κΈ°λ³Έ λ™μž‘μ„ μ‚¬μš©μž μ •μ˜ 객체 μž‘μ—… μ€‘μž¬ 및 κ°€λ‘œμ±„κΈ° κ°€λŠ₯ const person = new Proxy({ name: '홍길동' }, { get(obj, prop) { return prop in obj ? obj[prop] : '속성이 μ—†μŠ΅λ‹ˆλ‹€'; } });

객체 λ¦¬ν„°λŸ΄ 방식

  • 단일 객체 λ§Œλ“€ λ•Œ κ°€μž₯ κ°„νŽΈν•˜κ²Œ 생성할 수 있음

  • 객체 λ¦¬ν„°λŸ΄μ€ μ€‘κ΄„ν˜Έ({})λ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό 직접 μƒμ„±ν•©λ‹ˆλ‹€. μ€‘κ΄„ν˜Έ μ•ˆμ— 속성과 값을 μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•˜μ—¬ μ •μ˜ν•©λ‹ˆλ‹€.

    const person = {
        name: '홍길동',
        age: 30,
        job: '개발자'
    };
  • 객체 λ¦¬ν„°λŸ΄μ˜ 쀑첩(Nesting) 객체 λ¦¬ν„°λŸ΄ 내에 λ‹€λ₯Έ 객체λ₯Ό μ€‘μ²©ν•˜μ—¬ λ³΅μž‘ν•œ 데이터 ꡬ쑰λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€

    const student = {
        name: '홍길동',
        age: 20,
        grades: {
            math: 95,
            science: 88,
            language: 92
        },
        address: {
            city: 'μ„œμšΈ',
            district: '강남ꡬ',
            details: {
                street: 'ν…Œν—€λž€λ‘œ',
                building: '123동'
            }
        }
    };
    
    // μ€‘μ²©λœ 속성에 μ ‘κ·Ό
    console.log(student.grades.math);  // 95
    console.log(student.address.details.street);  // 'ν…Œν—€λž€λ‘œ'
    • 이 λ•Œ κ°μ²΄μ•ˆμ— μ€‘μ²©λœ 객체듀도 독립적인 κ°μ²΄λ‘œμ„œ 쑴재

μƒμ„±μž ν•¨μˆ˜

  • μƒμ„±μž ν•¨μˆ˜λŠ” κ΅¬λ¬Έμ μœΌλ‘œλŠ” 일반 ν•¨μˆ˜μ™€ 동일
    • λ‹€λ§Œ 호좜 ν•  λ•Œ new ν‚€μ›Œλ“œλ₯Ό 톡해 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒˆλ‘œμš΄κ°μ²΄λ₯Ό μƒμ„±ν•˜κ³  μ΄ˆκΈ°ν™”ν•¨

    • new ν‚€μ›Œλ“œλ§Œ 뢙이면 일반 ν•¨μˆ˜λ„ μƒμ„±μž ν•¨μˆ˜μ²˜λŸΌ 무쑰건 ν˜ΈμΆœν•  수 μžˆλŠ”κ±°μž„?

      κΈ°μˆ μ μœΌλ‘œλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λͺ¨λ“  ν•¨μˆ˜λŠ” new ν‚€μ›Œλ“œμ™€ ν•¨κ»˜ ν˜ΈμΆœν•  수 μžˆμ–΄ μƒμ„±μžμ²˜λŸΌ μ‚¬μš©ν•  수 있음. ν•˜μ§€λ§Œ 이게 μ’‹κ±°λ‚˜ μ˜λ„λœκ±΄ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— ꡬ별을 μœ„ν•œ λͺ‡κ°€μ§€ 방법듀을 μ‚¬μš©ν•¨

      1. λͺ…λͺ… κ·œμΉ™ (μ»¨λ²€μ…˜)

      • μƒμ„±μž ν•¨μˆ˜: 파슀칼 μΌ€μ΄μŠ€(PascalCase)둜 첫 κΈ€μžλ₯Ό λŒ€λ¬Έμžλ‘œ μ”λ‹ˆλ‹€ (예: Person, Product)
      • 일반 ν•¨μˆ˜: 카멜 μΌ€μ΄μŠ€(camelCase)둜 첫 κΈ€μžλ₯Ό μ†Œλ¬Έμžλ‘œ μ”λ‹ˆλ‹€ (예: calculateTax, getUserData)
      • κ·œμΉ™μ— μ˜ν•΄ νŒλ‹¨ν•˜λŠ”κ±°λΌ λ‹Ήμ—°νžˆ νœ΄λ¨Όμ—λŸ¬λ‚  ν™•λ₯  많음!

      2. λ‚΄λΆ€ 섀계와 this 바인딩

      μƒμ„±μž ν•¨μˆ˜λŠ” 일반적으둜 this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆλ‘œ 생성될 객체의 속성을 μ΄ˆκΈ°ν™”ν•˜λ„λ‘ μ„€κ³„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€:

      // μƒμ„±μž ν•¨μˆ˜ - thisλ₯Ό μ‚¬μš©ν•˜μ—¬ 객체 속성 μ„€μ •
      function Car(make, model) {
        this.make = make;
        this.model = model;
        this.isRunning = false;
      }
      
      // 일반 ν•¨μˆ˜ - 객체λ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ λ‹€λ₯Έ μž‘μ—… μˆ˜ν–‰
      function createCar(make, model) {
        return {
          make: make,
          model: model,
          isRunning: false
        };
      }

      μƒμ„±μž ν•¨μˆ˜λŠ” 보톡 아무것도 λͺ…μ‹œμ μœΌλ‘œ λ°˜ν™˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹  thisκ°€ μ•”λ¬΅μ μœΌλ‘œ λ°˜ν™˜λ©λ‹ˆλ‹€. 일반 ν•¨μˆ˜λŠ” 보톡 값을 κ³„μ‚°ν•˜κ±°λ‚˜ λͺ…μ‹œμ μœΌλ‘œ 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

      3. ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” κ°’

      μƒμ„±μž ν•¨μˆ˜μ™€ 일반 ν•¨μˆ˜λŠ” λ°˜ν™˜ κ°’ μ²˜λ¦¬μ—μ„œλ„ 차이가 μžˆμŠ΅λ‹ˆλ‹€:

      // μƒμ„±μž ν•¨μˆ˜ - **객체λ₯Ό λ°˜ν™˜ν•˜λ©΄ this λŒ€μ‹  κ·Έ 객체가 λ°˜ν™˜λ¨**
      function StrangeCtor() {
        this.prop = 1;
        return { differentProp: 2 }; // 이 객체가 λ°˜ν™˜λ¨
      }
      
      // μƒμ„±μž ν•¨μˆ˜ - **μ›μ‹œκ°’μ„ λ°˜ν™˜ν•˜λ©΄ λ¬΄μ‹œλ˜κ³  thisκ°€ λ°˜ν™˜λ¨**
      function NormalCtor() {
        this.prop = 1;
        return 42; // λ¬΄μ‹œλ¨, thisκ°€ λ°˜ν™˜λ¨
      }
      
      const strange = new StrangeCtor();
      console.log(strange.prop); // undefined
      console.log(strange.differentProp); // 2
      
      const normal = new NormalCtor();
      console.log(normal.prop); // 1

      μƒμ„±μž ν•¨μˆ˜μ—μ„œ 객체λ₯Ό λͺ…μ‹œμ μœΌλ‘œ λ°˜ν™˜ν•˜λ©΄ this λŒ€μ‹  κ·Έ 객체가 λ°˜ν™˜λ˜κ³ , μ›μ‹œκ°’μ„ λ°˜ν™˜ν•˜λ©΄ λ¬΄μ‹œλ˜κ³  thisκ°€ λ°˜ν™˜λ©λ‹ˆλ‹€.

      일반 ν•¨μˆ˜λ₯Ό μƒμ„±μžλ‘œ ν˜ΈμΆœν•˜λŠ” 경우의 문제점

      일반 ν•¨μˆ˜λ₯Ό new와 ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄ μ˜ˆμƒμΉ˜ λͺ»ν•œ λ™μž‘μ΄ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€:

      function add(a, b) {
        return a + b;
      }
      
      const result = new add(3, 5);
      console.log(result); // add {}
      console.log(result instanceof add); // true
      console.log(result.constructor === add); // true

      μœ„ μ˜ˆμ œμ—μ„œ new add(3, 5)λŠ” 빈 객체λ₯Ό μƒμ„±ν•˜κ³  add ν•¨μˆ˜μ˜ prototypeκ³Ό μ—°κ²°ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ add ν•¨μˆ˜λŠ” thisλ₯Ό μ‚¬μš©ν•˜μ—¬ 속성을 μΆ”κ°€ν•˜μ§€ μ•ŠμœΌλ©°, ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” 값은 숫자(μ›μ‹œκ°’)μ΄λ―€λ‘œ λ¬΄μ‹œλ©λ‹ˆλ‹€. 결과적으둜 빈 객체가 λ°˜ν™˜λ©λ‹ˆλ‹€.

      μƒμ„±μž ν•¨μˆ˜λ₯Ό 일반 ν•¨μˆ˜λ‘œ ν˜ΈμΆœν•˜λŠ” 경우의 문제점

      μƒμ„±μž ν•¨μˆ˜λ₯Ό new 없이 ν˜ΈμΆœν•˜λ©΄ 더 μ‹¬κ°ν•œ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€:

      function Person(name) {
        this.name = name;
      }
      
      // new 없이 호좜
      const person = Person('홍길동');
      console.log(person); // undefined (ν•¨μˆ˜κ°€ λͺ…μ‹œμ μœΌλ‘œ λ°˜ν™˜ν•˜λŠ” 값이 μ—†μŒ)
      console.log(name); // '홍길동' (μ „μ—­ 객체에 name 속성이 좔가됨)

      new 없이 호좜되면 thisλŠ” μ „μ—­ 객체(λΈŒλΌμš°μ €μ—μ„œλŠ” window, Node.jsμ—μ„œλŠ” global)λ₯Ό κ°€λ¦¬ν‚΅λ‹ˆλ‹€. λ”°λΌμ„œ Person('홍길동')은 μ „μ—­ 객체에 name 속성을 μΆ”κ°€ν•˜λŠ” κ²°κ³Όλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€. μ΄λŠ” μ˜λ„ν•˜μ§€ μ•Šμ€ μ „μ—­ λ³€μˆ˜ μ˜€μ—Όμ„ μΌμœΌν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

      μƒμ„±μž ν•¨μˆ˜μ˜ μ•ˆμ „ν•œ κ΅¬ν˜„

      μ΄λŸ¬ν•œ 문제λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ μƒμ„±μž ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같이 κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

      // Scope-safe Constructor νŒ¨ν„΄
      // ES6 이전에 많이 μ‚¬μš©λ˜λ˜
      function SafePerson(name) {
        // new 없이 호좜된 경우 new와 ν•¨κ»˜ λ‹€μ‹œ 호좜
        **if (!(this instanceof SafePerson)) {
          return new SafePerson(name);
        }**
      
        this.name = name;
      }
      
      // new 없이 ν˜ΈμΆœν•΄λ„ μ•ˆμ „ν•¨
      const person1 = SafePerson('홍길동');
      console.log(person1.name); // '홍길동'
      
      // 일반적인 new ν˜ΈμΆœλ„ 정상 μž‘λ™
      const person2 = new SafePerson('κΉ€μ² μˆ˜');
      console.log(person2.name); // 'κΉ€μ² μˆ˜'

      ν˜Ήμ€ new.target 을 ν†΅ν•΄μ„œλ„ κ°€λŠ₯ν•˜λ‹€

      function SafePerson(name) {
        // new.target이 undefined이면 new 없이 호좜된 것
        if (!new.target) {
          return new SafePerson(name);
        }
        
        this.name = name;
      }
      
      // new 없이 ν˜ΈμΆœν•΄λ„ μ•ˆμ „ν•¨
      const person1 = SafePerson('홍길동');
      console.log(person1.name); // '홍길동'
      
      // 일반적인 new ν˜ΈμΆœλ„ 정상 μž‘λ™
      const person2 = new SafePerson('κΉ€μ² μˆ˜');
      console.log(person2.name); // 'κΉ€μ² μˆ˜'

      new.target은 ES6μ—μ„œ λ„μž…λœ 메타 ν”„λ‘œνΌν‹°λ‘œ, ν•¨μˆ˜κ°€ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€λ₯Ό ν™•μΈν•˜λŠ” 더 ν˜„λŒ€μ μΈ λ°©λ²•μž…λ‹ˆλ‹€.

      new.target의 μž₯점은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

      1. 더 λͺ…ν™•ν•œ μ˜λ„ ν‘œν˜„: new.target은 λͺ…μ‹œμ μœΌλ‘œ ν•¨μˆ˜κ°€ μƒμ„±μžλ‘œ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•œ λͺ©μ μœΌλ‘œ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
      2. 상속 κ΄€κ³„μ—μ„œ 더 μ •ν™•ν•œ λ™μž‘: 상속 κ΄€κ³„μ—μ„œ this instanceof Constructor μ²΄ν¬λŠ” λ•Œλ‘œ μ˜ˆμƒμΉ˜ λͺ»ν•œ κ²°κ³Όλ₯Ό λ‚Ό 수 μžˆμ§€λ§Œ, new.target은 항상 ν˜„μž¬ 호좜된 μƒμ„±μžλ₯Ό μ •ν™•νžˆ κ°€λ¦¬ν‚΅λ‹ˆλ‹€.
      3. 클래슀 λ‚΄λΆ€μ—μ„œλ„ μ‚¬μš© κ°€λŠ₯: new.target은 ES6 클래슀의 μƒμ„±μž λ‚΄λΆ€μ—μ„œλ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

      ES6 ν΄λž˜μŠ€μ™€μ˜ 비ꡐ

      ES6μ—μ„œ λ„μž…λœ ν΄λž˜μŠ€λŠ” μ΄λŸ¬ν•œ ν˜Όλž€μ„ 쀄이기 μœ„ν•œ 방법 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€:

      class Person {
        constructor(name) {
          this.name = name;
        }
      }
      
      // ν΄λž˜μŠ€λŠ” λ°˜λ“œμ‹œ new와 ν•¨κ»˜ ν˜ΈμΆœν•΄μ•Ό 함
      // const person = Person('홍길동'); 
      // TypeError: Class constructor Person cannot be invoked without 'new'
      const person = new Person('홍길동'); // 정상 μž‘λ™

      클래슀 μƒμ„±μžλŠ” new 없이 ν˜ΈμΆœν•  수 μ—†μœΌλ―€λ‘œ, 이 문제λ₯Ό μ›μ²œμ μœΌλ‘œ λ°©μ§€ν•©λ‹ˆλ‹€.

// μƒμ„±μž ν•¨μˆ˜ μ •μ˜
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    return `μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€!`;
  };
}

// μƒμ„±μž ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ 객체 생성
const person1 = new Person('홍길동', 30);
const person2 = new Person('κΉ€μ² μˆ˜', 25);

console.log(person1.name); // '홍길동'
console.log(person2.greet()); // 'μ•ˆλ…•ν•˜μ„Έμš”, κΉ€μ² μˆ˜μž…λ‹ˆλ‹€!'

μƒμ„±μž ν•¨μˆ˜ μž‘λ™ 원리

μƒμ„±μž ν•¨μˆ˜κ°€ new ν‚€μ›Œλ“œμ™€ ν•¨κ»˜ 호좜될 λ•Œ λ‚΄λΆ€μ μœΌλ‘œ μΌμ–΄λ‚˜λŠ” 일은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  1. μƒˆλ‘œμš΄ 빈 객체가 μƒμ„±λ©λ‹ˆλ‹€.
  2. 이 객체의 [[Prototype]](λ˜λŠ” __proto__)이 μƒμ„±μž ν•¨μˆ˜μ˜ prototype 속성과 μ—°κ²°λ©λ‹ˆλ‹€.
  3. ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisκ°€ μƒˆλ‘œ μƒμ„±λœ 객체λ₯Ό 가리킀도둝 μ„€μ •λ©λ‹ˆλ‹€.
  4. ν•¨μˆ˜ 본문의 μ½”λ“œκ°€ μ‹€ν–‰λ˜μ–΄ thisλ₯Ό 톡해 객체에 속성과 λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.
  5. ν•¨μˆ˜κ°€ λͺ…μ‹œμ μœΌλ‘œ λ‹€λ₯Έ 객체λ₯Ό λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” ν•œ, this에 λ°”μΈλ”©λœ μƒˆ 객체가 λ°˜ν™˜λ©λ‹ˆλ‹€.
    1. 이 λ•Œ λͺ…μ‹œμ μœΌλ‘œ μ›μ‹œκ°’μ„ λ°˜ν™˜ν•˜λŠ” κ²½μš°μ—λŠ” λ¬΄μ‹œλ˜κ³  thisκ°€ λ°˜ν™˜λ¨
function new(Constructor, ...args) {
  // 1. μƒˆλ‘œμš΄ 빈 객체 생성
  const obj = {};
  
  // 2. 객체의 ν”„λ‘œν† νƒ€μž… μ„€μ •
  Object.setPrototypeOf(obj, Constructor.prototype);
  
  // 3 & 4. μƒμ„±μž ν•¨μˆ˜ μ‹€ν–‰, thisλ₯Ό μƒˆ 객체에 바인딩
  const result = Constructor.apply(obj, args);
  
  // 5. μƒμ„±μžμ˜ λ°˜ν™˜κ°’μ΄ 객체면 κ·Έ 객체λ₯Ό, μ•„λ‹ˆλ©΄ μƒˆ 객체 λ°˜ν™˜
  return (typeof result === 'object' && result !== null) ? result : obj;
}

μƒμ„±μž ν•¨μˆ˜ 넀이밍 μ»¨λ²€μ…˜

μƒμ„±μž ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜μ™€ κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ 첫 κΈ€μžλ₯Ό λŒ€λ¬Έμžλ‘œ μž‘μ„±ν•˜λŠ” 파슀칼 μΌ€μ΄μŠ€(PascalCase) 넀이밍 μ»¨λ²€μ…˜μ„ 따름

// 일반 ν•¨μˆ˜ - 카멜 μΌ€μ΄μŠ€
function calculateArea(radius) {
  return Math.PI * radius * radius;
}

// μƒμ„±μž ν•¨μˆ˜ - 파슀칼 μΌ€μ΄μŠ€
function Circle(radius) {
  this.radius = radius;
  this.getArea = function() {
    return Math.PI * this.radius * this.radius;
  };
}

ν”„λ‘œν† νƒ€μž…κ³Ό μƒμ„±μž ν•¨μˆ˜

μƒμ„±μž ν•¨μˆ˜λ‘œ 객체λ₯Ό 생성할 λ•Œ μ£Όμ˜ν•  점은 λͺ¨λ“  μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ λ©”μ„œλ“œκ°€ 쀑볡 μƒμ„±λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ΄λŠ” λ©”λͺ¨λ¦¬ νš¨μœ¨μ„±μ„ μ €ν•˜μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€:

function Person(name) {
  this.name = name;
  // 각 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ λ™μΌν•œ ν•¨μˆ˜κ°€ λ©”λͺ¨λ¦¬μ— 쀑볡 생성됨
  this.greet = function() {
    return `μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€!`;
  };
}

const p1 = new Person('홍길동');
const p2 = new Person('κΉ€μ² μˆ˜');

console.log(p1.greet === p2.greet); // false (λ‹€λ₯Έ ν•¨μˆ˜ 객체)

이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ν”„λ‘œν† νƒ€μž…μ„ ν™œμš©ν•©λ‹ˆλ‹€. ν”„λ‘œν† νƒ€μž…μ— λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λ©΄ λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ 이λ₯Ό κ³΅μœ ν•˜λ―€λ‘œ λ©”λͺ¨λ¦¬ νš¨μœ¨μ„±μ΄ ν–₯μƒλ©λ‹ˆλ‹€

function Person(name) {
  this.name = name;
  // μΈμŠ€ν„΄μŠ€ μ†μ„±λ§Œ 여기에 μ •μ˜
}

// ν”„λ‘œν† νƒ€μž…μ— λ©”μ„œλ“œ μ •μ˜ (λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ 곡유)
Person.prototype.greet = function() {
  return `μ•ˆλ…•ν•˜μ„Έμš”, ${this.name}μž…λ‹ˆλ‹€!`;
};

const p1 = new Person('홍길동');
const p2 = new Person('κΉ€μ² μˆ˜');

console.log(p1.greet === p2.greet); // true (같은 ν•¨μˆ˜ 객체 μ°Έμ‘°)

ν”„λ‘œν† νƒ€μž…μ€ λ‹€μŒ μ±•ν„°μ—μ„œ 더 μƒμ„Ένžˆ μ„€λͺ…

μƒμ„±μž ν•¨μˆ˜μ˜ μž₯단점

μž₯점:

  1. λ™μΌν•œ ꡬ쑰의 객체λ₯Ό μ—¬λŸ¬ 개 생성할 λ•Œ μ½”λ“œ 쀑볡을 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.
  2. ν”„λ‘œν† νƒ€μž…μ„ 톡해 λ©”μ„œλ“œλ₯Ό κ³΅μœ ν•˜μ—¬ λ©”λͺ¨λ¦¬ νš¨μœ¨μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
  3. 객체가 μ–΄λ–€ μƒμ„±μžλ‘œλΆ€ν„° λ§Œλ“€μ–΄μ‘ŒλŠ”μ§€ μ‰½κ²Œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€(instanceof).
  4. ES6 μ΄μ „μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°μ˜ κΈ°λ³Έ νŒ¨ν„΄μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

단점:

  1. ν”„λ‘œν† νƒ€μž… 상속 κ΅¬ν˜„μ΄ 직관적이지 μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  2. new ν‚€μ›Œλ“œλ₯Ό μžŠμ–΄λ²„λ¦¬λ©΄ μ˜ˆμƒμΉ˜ λͺ»ν•œ 버그가 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  3. ES6 ν΄λž˜μŠ€μ— λΉ„ν•΄ 문법이 덜 λͺ…ν™•ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  4. 프라이빗 속성(private properties)을 기본적으둜 μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μƒμ„±μž ν•¨μˆ˜λŠ” ES6 ν΄λž˜μŠ€κ°€ λ„μž…λ˜κΈ° 전에 μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°μ„ κ΅¬ν˜„ν•˜λŠ” μ£Όμš” λ°©λ²•μ΄μ—ˆμŠ΅λ‹ˆλ‹€. μ˜€λŠ˜λ‚ μ—λ„ λ§Žμ€ λ ˆκ±°μ‹œ μ½”λ“œμ—μ„œ 이 νŒ¨ν„΄μ„ λ³Ό 수 있으며, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν”„λ‘œν† νƒ€μž… 기반 상속을 μ΄ν•΄ν•˜λŠ” 데 μ€‘μš”ν•œ κ°œλ…μž…λ‹ˆλ‹€. ES6 ν΄λž˜μŠ€κ°€ 보닀 ν˜„λŒ€μ μΈ 문법을 μ œκ³΅ν•˜μ§€λ§Œ, λ‚΄λΆ€μ μœΌλ‘œλŠ” μ—¬μ „νžˆ ν”„λ‘œν† νƒ€μž… 기반의 μƒμ„±μž ν•¨μˆ˜ λ©”μ»€λ‹ˆμ¦˜μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

ν•¨μˆ˜μ™€ 객체의 차이 그리고 λ‚΄λΆ€μŠ¬λ¦‡

  • ν•¨μˆ˜λŠ” κ°μ²΄μ΄μ§€λ§Œ 일반 객체와 λ‹€λ₯΄λ‹€.
  • 일반 κ°μ²΄λŠ” ν˜ΈμΆœν•  수 μ—†μ§€λ§Œ(call) ν•¨μˆ˜λŠ” ν˜ΈμΆœν•  수 μžˆλ‹€.
  • κ·Έλž˜μ„œ ν•¨μˆ˜λŠ” 일반 객체와 달리 ν˜ΈμΆœμ„ μœ„ν•œ 좔가적인 λ‚΄λΆ€μŠ¬λ¦‡μ„ κ°€μ§€κ³  μžˆλ‹€.

ν•¨μˆ˜ 객체의 λ‚΄λΆ€ 슬둯 (Internal Slots)

λ‚΄λΆ€ 슬둯 μ„€λͺ… μ—­ν• 
[[Call]] ν•¨μˆ˜ 호좜 μ‹œ μ‹€ν–‰λ˜λŠ” λ‚΄λΆ€ λ©”μ„œλ“œ ν•¨μˆ˜κ°€ 일반 ν•¨μˆ˜λ‘œμ„œ 호좜될 λ•Œ (func() ν˜•νƒœ) μ‹€ν–‰λ˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ„ μ •μ˜
[[Construct]] μƒμ„±μž 호좜 μ‹œ μ‹€ν–‰λ˜λŠ” λ‚΄λΆ€ λ©”μ„œλ“œ ν•¨μˆ˜κ°€ μƒμ„±μž ν•¨μˆ˜λ‘œμ„œ 호좜될 λ•Œ (new func() ν˜•νƒœ) μ‹€ν–‰λ˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ„ μ •μ˜
[[Environment]] ν•¨μˆ˜μ˜ λ ‰μ‹œμ»¬ ν™˜κ²½μ„ μ°Έμ‘° ν•¨μˆ˜κ°€ μ •μ˜λœ ν™˜κ²½(μŠ€μ½”ν”„)을 κΈ°μ–΅ν•˜μ—¬ ν΄λ‘œμ €λ₯Ό κ΅¬ν˜„
[[FormalParameters]] ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ λͺ©λ‘ μ €μž₯ ν•¨μˆ˜ 호좜 μ‹œ μΈμˆ˜μ™€ λ§€κ°œλ³€μˆ˜λ₯Ό λ§€ν•‘ν•˜λŠ” 데 μ‚¬μš©
[[ECMAScriptCode]] ν•¨μˆ˜μ˜ μ‹€ν–‰ μ½”λ“œ μ €μž₯ ν•¨μˆ˜ 호좜 μ‹œ 싀행될 μ½”λ“œλ₯Ό 보관
[[ScriptOrModule]] ν•¨μˆ˜κ°€ μ •μ˜λœ μŠ€ν¬λ¦½νŠΈλ‚˜ λͺ¨λ“ˆ μ°Έμ‘° ν•¨μˆ˜μ˜ μΆœμ²˜μ™€ λͺ¨λ“ˆ κ΄€λ ¨ 정보λ₯Ό 관리
[[Realm]] ν•¨μˆ˜κ°€ μ†ν•œ μ‹€ν–‰ ν™˜κ²½ 정보 μ „μ—­ 객체 λ“± ν•¨μˆ˜ 싀행에 ν•„μš”ν•œ ν™˜κ²½ 정보 관리
[[HomeObject]] λ©”μ„œλ“œκ°€ μ •μ˜λœ 객체 μ°Έμ‘° (ES6+) super ν‚€μ›Œλ“œ λ™μž‘μ— ν•„μš”ν•œ 정보 제곡
[[IsClassConstructor]] 클래슀 μƒμ„±μž μ—¬λΆ€ (ES6+) 클래슀 μƒμ„±μžμ˜ new μ—†λŠ” 호좜 λ°©μ§€
[[InitialName]] ν•¨μˆ˜μ˜ μ›λž˜ 이름 (λ””λ²„κΉ…μš©) 개발 λ„κ΅¬μ—μ„œ ν•¨μˆ˜ 식별에 도움

일반 객체와 ν•¨μˆ˜ 객체의 곡톡 λ‚΄λΆ€ 슬둯

λ‚΄λΆ€ 슬둯 μ„€λͺ…
[[Prototype]] ν”„λ‘œν† νƒ€μž… 객체에 λŒ€ν•œ μ°Έμ‘° (상속)
[[Extensible]] 객체의 ν™•μž₯ κ°€λŠ₯ μ—¬λΆ€
[[OwnPropertyKeys]] 객체 μžμ‹ μ˜ λͺ¨λ“  ν”„λ‘œνΌν‹° ν‚€ λͺ©λ‘

ν•¨μˆ˜ 객체의 μ ‘κ·Ό κ°€λŠ₯ν•œ νŠΉλ³„ ν”„λ‘œνΌν‹°

ν”„λ‘œνΌν‹° μ„€λͺ… μ˜ˆμ‹œ
name ν•¨μˆ˜μ˜ 이름 function foo() {}; console.log(foo.name); // "foo"
length ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ˜ 수 function(a, b, c) {}; // lengthλŠ” 3
prototype μƒμ„±μž ν•¨μˆ˜κ°€ μƒμ„±ν•˜λŠ” 객체의 ν”„λ‘œν† νƒ€μž… MyConstructor.prototype.method = function() {};
arguments ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œ μ „λ‹¬λœ μΈμˆ˜λ“€ function f() { console.log(arguments); }
caller ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ ν•¨μˆ˜ (λΉ„ν‘œμ€€) function inner() { console.log(inner.caller); }
  • μ–΄λ–  ν•¨μˆ˜κ°€ 일반 호좜될 λ•ŒλŠ” [[Call]] μƒμ„±μž ν•¨μˆ˜λ‘œ 호좜될 λ•ŒλŠ” [[Constructor]] κ°€ μ‹€ν–‰λœλ‹€.
function foo() {}

// [[Call]이 호좜
foo();

// [[Constructor]]
new foo();
  • 이 λ•Œ λ‚΄λΆ€ λ©”μ„œλ“œ [[Call]] 을 κ°€μ§€λŠ” ν•¨μˆ˜κ°μ²΄λ₯Ό callable 이라고 ν•œλ‹€.
  • λ‚΄λΆ€ λ©”μ„œλ“œ [[Constructor]] 을 κ°–λŠ” ν•¨μˆ˜ 객체λ₯Ό constructor 라고 λΆ€λ₯Έλ‹€.
  • λ‚΄λΆ€ λ©”μ„œλ“œ [[Constructor]] 을 κ°–μ§€μ•ŠλŠ” ν•¨μˆ˜ 객체λ₯Ό non-constructor 라고 λΆ€λ₯Έλ‹€. ch-17-1.png 근데 이거 λ§žλŠ” 그림이 μ•„λ‹Œκ±° 같은데 객체가 κ°€μ§€κ³  μžˆλŠ” λ‚΄λΆ€λ©”μ„œλ“œλ‘œ 그린건가?
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚    ν•¨μˆ˜ 객체 (λͺ¨λ‘ Callable)    β”‚
    β”‚                             β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
    β”‚  β”‚ Constructor   β”‚          β”‚
    β”‚  β”‚    ν•¨μˆ˜       β”‚          β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
    β”‚                             β”‚
    β”‚  ───────── Non-────────────  β”‚
    β”‚       Constructor ν•¨μˆ˜      β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  • ν˜ΈμΆœν•  수 μ—†λŠ” κ°μ²΄λŠ” ν•¨μˆ˜ 객체가 μ•„λ‹ˆλ―€λ‘œ λͺ¨λ“  ν•¨μˆ˜λŠ” λ°˜λ“œμ‹œ callable μ΄μ–΄μ•Όν•œλ‹€.
    • λ”°λΌμ„œ λͺ¨λ“  ν•¨μˆ˜ κ°μ²΄λŠ” λ‚΄λΆ€ λ©”μ„œλ“œ [[Call]] 을 κ°€μ§€κ³  있고 ν˜ΈμΆœν•  수 μžˆλ‹€. (μ˜λ„μ™€λŠ” λ³„κ°œλ‘œ)
  • κ·ΈλŸ¬λ‚˜ λͺ¨λ“  ν•¨μˆ˜ 객체가 [[Constructor]] 을 κ°€μ§€λŠ”κ±΄ μ•„λ‹ˆλ‹€.
    • λ”°λΌμ„œ ν•¨μˆ˜ κ°μ²΄λŠ” constructor 일 μˆ˜λ„ 있고 non-constructor 일 수 μžˆλ‹€.
  • 결둠적으둜 λͺ¨λ“  ν•¨μˆ˜ κ°μ²΄λŠ” callable μ΄λ©΄μ„œ constructor μ΄κ±°λ‚˜ callable μ΄λ©΄μ„œ non-constructorλ‹€.

Constructor(μƒμ„±μž) ν•¨μˆ˜μ™€ Non-constructor(λΉ„μƒμ„±μž) ν•¨μˆ˜ 비ꡐ

ꡬ뢄 Constructor(μƒμ„±μž) Non-constructor(λΉ„μƒμ„±μž)
μ •μ˜ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό 생성할 수 μžˆλŠ” ν•¨μˆ˜ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•  수 μ—†λŠ” ν•¨μˆ˜
λ‚΄λΆ€ 슬둯 [[Construct]] λ‚΄λΆ€ 슬둯 보유 [[Construct]] λ‚΄λΆ€ 슬둯 미보유
호좜 방식 일반 ν•¨μˆ˜λ‘œλ„ 호좜 κ°€λŠ₯, μƒμ„±μž ν•¨μˆ˜λ‘œλ„ 호좜 κ°€λŠ₯ 였직 일반 ν•¨μˆ˜λ‘œλ§Œ 호좜 κ°€λŠ₯

constructor 와 non-constructor

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λŠ” constructor(μƒμ„±μž)와 non-constructor(λΉ„μƒμ„±μž)둜 ꡬ뢄할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 ꡬ뢄은 ν•¨μˆ˜κ°€ new μ—°μ‚°μžμ™€ ν•¨κ»˜ μƒμ„±μžλ‘œμ„œ 호좜될 수 μžˆλŠ”μ§€ 여뢀에 κ΄€ν•œ κ²ƒμž…λ‹ˆλ‹€.

Constructor(μƒμ„±μž) ν•¨μˆ˜ μ’…λ₯˜

ν•¨μˆ˜ μœ ν˜• μ„€λͺ… μ˜ˆμ‹œ
ν•¨μˆ˜ μ„ μ–Έλ¬Έ function ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ 일반 ν•¨μˆ˜ function Foo() {}
ν•¨μˆ˜ ν‘œν˜„μ‹ λ³€μˆ˜μ— ν• λ‹Ήλœ 읡λͺ… ν•¨μˆ˜ const Foo = function() {};
μƒμ„±μž ν•¨μˆ˜ λͺ…μ‹œμ μœΌλ‘œ 객체 생성을 μœ„ν•΄ μ„€κ³„λœ ν•¨μˆ˜ function Person(name) { this.name = name; }
클래슀 μ„ μ–Έλ¬Έ ES6μ—μ„œ λ„μž…λœ 클래슀 λ¬Έλ²•μœΌλ‘œ μ„ μ–Έλœ ν•¨μˆ˜ class Person {}
클래슀 ν‘œν˜„μ‹ λ³€μˆ˜μ— ν• λ‹Ήλœ 클래슀 const Person = class {};
Function μƒμ„±μž new Function()으둜 μƒμ„±λœ ν•¨μˆ˜ const add = new Function('a', 'b', 'return a + b');

Non-constructor(λΉ„μƒμ„±μž) ν•¨μˆ˜ μ’…λ₯˜

ν•¨μˆ˜ μœ ν˜• μ„€λͺ… μ˜ˆμ‹œ
ν™”μ‚΄ν‘œ ν•¨μˆ˜ ES6μ—μ„œ λ„μž…λœ => λ¬Έλ²•μ˜ ν•¨μˆ˜ const add = (a, b) => a + b;
λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„ ES6μ—μ„œ λ„μž…λœ 객체 λ¦¬ν„°λŸ΄ λ‚΄ λ©”μ„œλ“œ μΆ•μ•½ν˜• const obj = { method() { } };
클래슀 λ‚΄λΆ€ λ©”μ„œλ“œ 클래슀 내뢀에 μ •μ˜λœ λ©”μ„œλ“œ class Person { speak() { } }
μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜ function* λ¬Έλ²•μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜ function* gen() { yield 1; }

Constructor와 Non-constructor 식별 방법

function isConstructor(fn) {
  try {
    new fn();
    return true;
  } catch (error) {
    return false;
  }
}

// ν…ŒμŠ€νŠΈ μ˜ˆμ‹œ
function regularFunction() {}
const arrowFunction = () => {};
const methodObj = { method() {} };

console.log(isConstructor(regularFunction)); // true
console.log(isConstructor(arrowFunction)); // false
console.log(isConstructor(methodObj.method)); // false

Constructor ν•¨μˆ˜ 호좜 μ‹œ λ‚΄λΆ€ λ™μž‘

  1. 빈 객체 생성 및 this 바인딩
  2. 객체의 ν”„λ‘œν† νƒ€μž… μ„€μ •
  3. thisλ₯Ό ν†΅ν•œ ν”„λ‘œνΌν‹° μΆ”κ°€
  4. μƒμ„±λœ 객체 λ°˜ν™˜

Non-constructor ν•¨μˆ˜μ— new μ—°μ‚°μž μ‚¬μš© μ‹œ

  • TypeError: [ν•¨μˆ˜λͺ…] is not a constructor μ—λŸ¬ λ°œμƒ

ν—·κ°ˆλ¦¬λŠ” λ©”μ„œλ“œμ˜ 차이점

  • μœ„μ—μ„œ λ³΄μ•˜λ“― λ©”μ„œλ“œμ˜ κ²½μš°μ—λŠ” non-constructorλ‹€
  • κ·ΈλŸ¬λ‚˜ λ©”μ„œλ“œλ‘œ μΈμ •λ˜λŠ”κ±΄ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„λ§Œ λ©”μ„œλ“œλ‘œ μΈμ •λœλ‹€.
// 일반 ν•¨μˆ˜ μ •μ˜ : ν•¨μˆ˜ μ„ μ–Έλ¬Έ, ν•¨μˆ˜ ν‘œν˜„μ‹
function foo() {}
const bar = function() {};

// ν”„λ‘œνΌν‹° x의 κ°’μœΌλ‘œ ν• λ‹Ήλœ 것은 일반 ν•¨μˆ˜λ‘œ μ •μ˜λœ ν•¨μˆ˜μ΄λ‹€. 
// μ΄λŠ” λ©”μ„œλ“œλ‘œ μΈμ •ν•˜μ§€ μ•ŠλŠ”λ‹€.
const baz = {
	x: function () {}
}

// 일반 ν•¨μˆ˜λ‘œ μ •μ˜λœ ν•¨μˆ˜λ§Œμ΄ constructorλ‹€.
new foo(); // -> foo {}
new bar(); // -> bar {}
**new baz.x(); // -> x {}**

// ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‚˜ μΆ•μ•½ ν‘œν˜„λœ λ©”μ„œλ“œλŠ” non-constructor λ‹€.
const arrow = () => {};
new arrow(); // TypeError: arrow is not a constructor

// λ©”μ„œλ“œ μ •μ˜: ES6의 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„λ§Œ λ©”μ„œλ“œλ‘œ μΈμ •ν•œλ‹€.
const obj = {
	x() {}
	y: function () {}
};

new obj.x(); // TypeError: obj.x is not a constructor
new baz.y(); // -> y {}
  • 그럼 λ©”μ„œλ“œλž€ 뭐지?

    쒋은 μ§ˆλ¬Έμž…λ‹ˆλ‹€! μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ©”μ„œλ“œμ˜ μ •μ˜κ°€ μ–΄λ–»κ²Œ λ³€ν™”ν•΄μ™”λŠ”μ§€ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

    μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ©”μ„œλ“œμ˜ μ •μ˜

    μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ "λ©”μ„œλ“œ"λΌλŠ” μš©μ–΄λŠ” μ‹œκ°„μ΄ 지남에 따라 μ˜λ―Έκ°€ μ‘°κΈˆμ”© λ³€ν™”ν–ˆμŠ΅λ‹ˆλ‹€.

    전톡적인 μ •μ˜ (ES5 이전)

    μ „ν†΅μ μœΌλ‘œ λ©”μ„œλ“œλŠ” λ‹¨μˆœνžˆ "객체의 ν”„λ‘œνΌν‹°λ‘œ ν• λ‹Ήλœ ν•¨μˆ˜"λ₯Ό μ˜λ―Έν–ˆμŠ΅λ‹ˆλ‹€. 즉, 객체의 ν”„λ‘œνΌν‹° κ°’μœΌλ‘œ ν•¨μˆ˜κ°€ ν• λ‹Ήλ˜μ–΄ μžˆλ‹€λ©΄ 그것을 λ©”μ„œλ“œλΌκ³  λΆˆλ €μŠ΅λ‹ˆλ‹€.

    const obj = {
      x: function() {},  // 전톡적 의미의 λ©”μ„œλ“œ
      y: function() {}   // 전톡적 의미의 λ©”μ„œλ“œ
    };
    
    function Foo() {}
    obj.z = Foo;  // 이것도 전톡적 μ˜λ―Έμ—μ„œλŠ” λ©”μ„œλ“œ

    이 κ΄€μ μ—μ„œλŠ” λ©”μ„œλ“œκ°€ μ–΄λ–»κ²Œ μ •μ˜λ˜μ—ˆλŠ”μ§€λ³΄λ‹€ "객체에 μ†ν•œ ν•¨μˆ˜"λΌλŠ” 관계에 μ΄ˆμ μ„ λ§žμ·„μŠ΅λ‹ˆλ‹€.

    ν˜„λŒ€μ μΈ μ •μ˜ (ES6 이후)

    ES6λΆ€ν„°λŠ” λ©”μ„œλ“œμ˜ μ •μ˜κ°€ 더 λͺ…ν™•ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€. ECMAScript λͺ…μ„Έμ—μ„œλŠ” λ©”μ„œλ“œλ₯Ό "ES6의 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜"둜 더 ꡬ체적으둜 μ •μ˜ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ ν•¨μˆ˜λ“€μ€ [[HomeObject]] λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°–λŠ” νŠΉλ³„ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€.

    const obj = {
      x() {},        // ES6 λ©”μ„œλ“œ (μ§„μ§œ λ©”μ„œλ“œ)
      y: function() {} // ν•¨μˆ˜ ν”„λ‘œνΌν‹° (전톡적 의미의 λ©”μ„œλ“œμ§€λ§Œ, μ§„μ§œ λ©”μ„œλ“œλŠ” μ•„λ‹˜)
    };

    μ—¬κΈ°μ„œ xλŠ” ES6 λͺ…μ„Έμ—μ„œ λ§ν•˜λŠ” μ§„μ§œ "λ©”μ„œλ“œ"μž…λ‹ˆλ‹€. 이것은 non-constructor이며, [[HomeObject]] λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°€μ§€κ³  μžˆμ–΄ super ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 반면 yλŠ” ν•¨μˆ˜ ν‘œν˜„μ‹μ΄ 객체의 ν”„λ‘œνΌν‹°μ— ν• λ‹Ήλœ κ²ƒμœΌλ‘œ, constructorμž…λ‹ˆλ‹€.

    예제 뢄석

    κ·€ν•˜μ˜ 예제λ₯Ό λΆ„μ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€:

    const obj = {
      x() {},              // λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„ (ES6 λ©”μ„œλ“œ)
      y: function() {}     // ν•¨μˆ˜ ν‘œν˜„μ‹μ„ ν”„λ‘œνΌν‹° κ°’μœΌλ‘œ ν• λ‹Ή
    };
    
    new obj.x(); // TypeError: obj.x is not a constructor
    new obj.y(); // -> y {}
    • obj.xλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λ˜μ—ˆμœΌλ―€λ‘œ ES6 λͺ…μ„Έμ—μ„œ λ§ν•˜λŠ” μ§„μ§œ "λ©”μ„œλ“œ"μž…λ‹ˆλ‹€. 이것은 non-constructorμ΄λ―€λ‘œ new와 ν•¨κ»˜ ν˜ΈμΆœν•  수 μ—†μŠ΅λ‹ˆλ‹€.
    • obj.yλŠ” ν•¨μˆ˜ ν‘œν˜„μ‹μ΄ ν”„λ‘œνΌν‹°μ— ν• λ‹Ήλœ κ²ƒμž…λ‹ˆλ‹€. 이것은 constructorμ΄λ―€λ‘œ new와 ν•¨κ»˜ ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€. ES6 λͺ…μ„Έ κ΄€μ μ—μ„œλŠ” 이것은 "λ©”μ„œλ“œ"κ°€ μ•„λ‹ˆλΌ "ν•¨μˆ˜ ν”„λ‘œνΌν‹°"라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    κ²°λ‘ : λ©”μ„œλ“œλž€ 무엇인가?

    μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ "λ©”μ„œλ“œ"λΌλŠ” μš©μ–΄λŠ” 두 κ°€μ§€ κ΄€μ μ—μ„œ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€:

    1. κ΄‘μ˜μ˜ λ©”μ„œλ“œ (일반적인 ν”„λ‘œκ·Έλž˜λ° 관점): 객체에 μ†ν•œ λͺ¨λ“  ν•¨μˆ˜. 이 κ΄€μ μ—μ„œλŠ” obj.x와 obj.y λͺ¨λ‘ λ©”μ„œλ“œμž…λ‹ˆλ‹€.
    2. ν˜‘μ˜μ˜ λ©”μ„œλ“œ (ES6 λͺ…μ„Έ 관점): λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ, [[HomeObject]] λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°€μ§„ non-constructor ν•¨μˆ˜. 이 κ΄€μ μ—μ„œλŠ” obj.x만 λ©”μ„œλ“œμ΄κ³  obj.yλŠ” λ©”μ„œλ“œκ°€ μ•„λ‹™λ‹ˆλ‹€.

    ν˜„λŒ€ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” λ©”μ„œλ“œλΌλŠ” μš©μ–΄λ₯Ό 이야기할 λ•Œ 보톡 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜(ES6 λ©”μ„œλ“œ)λ₯Ό μ˜λ―Έν•˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. 이것이 ES6 λͺ…μ„Έμ—μ„œ μ •μ˜ν•˜λŠ” λ©”μ„œλ“œμ˜ 곡식적인 μ˜λ―Έμž…λ‹ˆλ‹€.

    λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜(ES6 λ©”μ„œλ“œ)λŠ” λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ κ°€μ§‘λ‹ˆλ‹€:

    1. non-constructorμž…λ‹ˆλ‹€. (new와 ν•¨κ»˜ ν˜ΈμΆœν•  수 μ—†μŒ)
    2. [[HomeObject]] λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°€μ§‘λ‹ˆλ‹€. (super μ°Έμ‘° κ°€λŠ₯)
    3. ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°κ°€ μ—†μŠ΅λ‹ˆλ‹€.

    이런 ꡬ뢄은 μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 객체 μ§€ν–₯ κΈ°λŠ₯을 κ°•ν™”ν•˜λ©΄μ„œ 생긴 κ²ƒμœΌλ‘œ, 객체의 λ©”μ„œλ“œκ°€ κ°€μ§€λŠ” νŠΉλ³„ν•œ 의미λ₯Ό λ°˜μ˜ν•©λ‹ˆλ‹€. 특히 super ν‚€μ›Œλ“œμ˜ μ‚¬μš©κ³Ό κ΄€λ ¨ν•΄ λ©”μ„œλ“œμ™€ 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹°λ₯Ό κ΅¬λΆ„ν•˜λŠ” 것이 μ€‘μš”ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

    λ”°λΌμ„œ 기술적으둜 μ •ν™•ν•œ 닡변은 "ES6 이후 μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ©”μ„œλ“œλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜"μž…λ‹ˆλ‹€λ§Œ, μ‹€λ¬΄μ—μ„œλŠ” μ—¬μ „νžˆ 객체의 ν”„λ‘œνΌν‹°μΈ ν•¨μˆ˜λ₯Ό 일반적으둜 λͺ¨λ‘ λ©”μ„œλ“œλΌκ³  λΆ€λ₯΄λŠ” κ²½μš°λ„ λ§ŽμŠ΅λ‹ˆλ‹€.

  • super ν‚€μ›Œλ“œμ™€ [[HomeObject]]의 관계

    super ν‚€μ›Œλ“œμ™€ λ©”μ„œλ“œ ꡬ뢄에 λŒ€ν•΄ 더 μžμ„Ένžˆ μ„€λͺ…ν•΄ λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€. 이 μ£Όμ œλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ° κΈ°λŠ₯κ³Ό 깊게 μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€

    super ν‚€μ›Œλ“œλŠ” ES6μ—μ„œ λ„μž…λ˜μ—ˆμœΌλ©°, μƒμœ„ ν”„λ‘œν† νƒ€μž…μ˜ λ©”μ„œλ“œλ‚˜ 속성에 μ ‘κ·Όν•  수 있게 ν•΄μ€λ‹ˆλ‹€. 이 κΈ°λŠ₯이 μ œλŒ€λ‘œ μž‘λ™ν•˜λ €λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 ν˜„μž¬ λ©”μ„œλ“œκ°€ μ–΄λ–€ 객체에 속해 μžˆλŠ”μ§€ μ•Œμ•„μ•Ό ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ ES6 λ©”μ„œλ“œλŠ” [[HomeObject]]λΌλŠ” νŠΉλ³„ν•œ λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°–μŠ΅λ‹ˆλ‹€.

    [[HomeObject]]λŠ” λ©”μ„œλ“œκ°€ μ†ν•œ 객체λ₯Ό μ°Έμ‘°ν•˜λŠ” λ‚΄λΆ€ 슬둯으둜, μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 super μ°Έμ‘°λ₯Ό ν•΄κ²°ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. 이 μŠ¬λ‘―μ€ 였직 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λ§Œ κ°€μ§€λ©°, 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹°λŠ” κ°€μ§€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

    const parent = {
      sayHello() {
        return "μ•ˆλ…•ν•˜μ„Έμš”!";
      }
    };
    
    const child = {
      __proto__: parent,
    
      // λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„ - [[HomeObject]]λ₯Ό 가짐
      sayHello() {
        return super.sayHello() + " λ°˜κ°‘μŠ΅λ‹ˆλ‹€!";
      },
    
      // 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹° - [[HomeObject]]κ°€ μ—†μŒ
      greet: function() {
        // Error: superλŠ” μ—¬κΈ°μ„œ μ‚¬μš©ν•  수 μ—†μŒ
        return super.sayHello() + " λ°˜κ°‘μŠ΅λ‹ˆλ‹€!";
      }
    };
    
    console.log(child.sayHello()); // "μ•ˆλ…•ν•˜μ„Έμš”! λ°˜κ°‘μŠ΅λ‹ˆλ‹€!"
    console.log(child.greet());    // Error: 'super' keyword unexpected here

    μœ„ μ˜ˆμ œμ—μ„œ sayHello()λŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λ˜μ—ˆκΈ° λ•Œλ¬Έμ— [[HomeObject]] μŠ¬λ‘―μ„ κ°€μ§€λ©°, 이λ₯Ό 톡해 super.sayHello()κ°€ μ˜¬λ°”λ₯΄κ²Œ λΆ€λͺ¨ 객체의 sayHello λ©”μ„œλ“œλ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    반면, greet은 일반 ν•¨μˆ˜ ν‘œν˜„μ‹μ΄ ν• λ‹Ήλœ κ²ƒμ΄λ―€λ‘œ [[HomeObject]] 슬둯이 μ—†κ³ , λ”°λΌμ„œ λ‚΄λΆ€μ—μ„œ superλ₯Ό μ‚¬μš©ν•˜λ €κ³  ν•˜λ©΄ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

    μ™œ 이런 ꡬ뢄이 μ€‘μš”ν•œκ°€?

    이 ꡬ뢄이 μ€‘μš”ν•œ μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

    1. 상속 λ©”μ»€λ‹ˆμ¦˜μ˜ λͺ…ν™•ν™”: ES6λŠ” ν΄λž˜μŠ€μ™€ ν•¨κ»˜ 더 λͺ…μ‹œμ μΈ 상속 λͺ¨λΈμ„ λ„μž…ν–ˆμŠ΅λ‹ˆλ‹€. super ν‚€μ›Œλ“œλŠ” 이 상속 λͺ¨λΈμ˜ 핡심 뢀뢄이며, λ©”μ„œλ“œμ™€ 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹°λ₯Ό κ΅¬λΆ„ν•¨μœΌλ‘œμ¨ 상속 관계가 더 λͺ…ν™•ν•΄μ§‘λ‹ˆλ‹€.
    2. λ©”μ„œλ“œ λ°”μΈλ”©μ˜ κ°„μ†Œν™”: λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λŠ” this 바인딩이 보닀 μ§κ΄€μ μž…λ‹ˆλ‹€. 일반 ν•¨μˆ˜μ™€ 달리, ν™”μ‚΄ν‘œ ν•¨μˆ˜μ²˜λŸΌ λ³„λ„μ˜ 바인딩 μž‘μ—… 없이도 μƒμœ„ μ»¨ν…μŠ€νŠΈμ˜ thisλ₯Ό ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    3. μ΅œμ ν™” 기회: μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ΄λŸ¬ν•œ ꡬ뢄을 톡해 λ©”μ„œλ“œ 호좜과 κ΄€λ ¨λœ μ΅œμ ν™”λ₯Ό 더 효과적으둜 μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    μ‹€μ œ 예제둜 μ‚΄νŽ΄λ³΄κΈ°

    λ‹€μŒ 예제λ₯Ό 톡해 더 ꡬ체적으둜 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€:

    // λΆ€λͺ¨ 객체
    const vehicle = {
      getSpeed() {
        return this.speed;
      },
    
      accelerate(increment) {
        this.speed += increment;
        return this.speed;
      }
    };
    
    // μžμ‹ 객체
    const car = {
      __proto__: vehicle,
      speed: 0,
    
      // ES6 λ©”μ„œλ“œ - super μ‚¬μš© κ°€λŠ₯
      accelerate(increment) {
        // λΆ€λͺ¨μ˜ accelerateλ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ μ¦κ°€λŸ‰μ„ 2배둜
        return super.accelerate(increment * 2);
      },
    
      // 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹°
      turboBoost: function(increment) {
        // λ‹€μŒ 쀄은 였λ₯˜ λ°œμƒ! - superλ₯Ό μ‚¬μš©ν•  수 μ—†μŒ
        // return super.accelerate(increment * 3);
    
        // λŒ€μ‹  λ‹€μŒκ³Ό 같이 ν•΄μ•Ό 함
        return vehicle.accelerate.call(this, increment * 3);
      }
    };
    
    car.speed = 10;
    console.log(car.accelerate(5));  // 20 (10 + 5*2)
    
    // λ‹€μŒκ³Ό 같이 λ©”μ„œλ“œλ₯Ό 별도 λ³€μˆ˜μ— ν• λ‹Ήν•˜λ©΄ μ–΄λ–»κ²Œ 될까?
    const carAccelerate = car.accelerate;
    // 이제 carAccelerateλŠ” [[HomeObject]]λ₯Ό μžƒμ§€ μ•Šκ³  μ—¬μ „νžˆ carλ₯Ό μ°Έμ‘°
    // ν•˜μ§€λ§Œ thisλŠ” undefined둜 λ°”λ€Œλ―€λ‘œ 직접 ν˜ΈμΆœν•˜λ©΄ 였λ₯˜ λ°œμƒ
    // carAccelerate(5); // 였λ₯˜: Cannot read property 'speed' of undefined

    이 μ˜ˆμ œμ—μ„œ car.accelerateλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λ˜μ—ˆμœΌλ―€λ‘œ [[HomeObject]] μŠ¬λ‘―μ„ κ°€μ§€λ©°, 이 μŠ¬λ‘―μ€ car 객체λ₯Ό μ°Έμ‘°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ super.accelerate()λŠ” car의 ν”„λ‘œν† νƒ€μž…μΈ vehicle의 accelerate λ©”μ„œλ“œλ₯Ό μ°Ύμ•„ ν˜ΈμΆœν•©λ‹ˆλ‹€.

    반면 car.turboBoostλŠ” 일반 ν•¨μˆ˜ ν‘œν˜„μ‹μ΄ ν• λ‹Ήλœ κ²ƒμ΄λ―€λ‘œ [[HomeObject]] 슬둯이 μ—†κ³ , superλ₯Ό μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λŒ€μ‹  vehicle.accelerate.call(this, ...)와 같은 λ°©μ‹μœΌλ‘œ λΆ€λͺ¨ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€.

    ν΄λž˜μŠ€μ—μ„œμ˜ 적용

    클래슀 λ‚΄μ—μ„œ μ •μ˜λœ λ©”μ„œλ“œλ“€λ„ λͺ¨λ‘ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„κ³Ό λ™μΌν•œ νŠΉμ„±μ„ κ°€μ§‘λ‹ˆλ‹€:

    class Animal {
      constructor(name) {
        this.name = name;
      }
    
      speak() {
        return `${this.name}이(κ°€) μ†Œλ¦¬λ₯Ό λƒ…λ‹ˆλ‹€`;
      }
    }
    
    class Dog extends Animal {
      speak() {
        // super.speak()λŠ” Animal.prototype.speak.call(this)와 κ°™μŒ
        return `${super.speak()}, 멍멍!`;
      }
    
      // 일반 ν•¨μˆ˜λ₯Ό 클래슀 ν•„λ“œμ— ν• λ‹Ή
      bark = function() {
        // λ‹€μŒ 쀄은 였λ₯˜ λ°œμƒ!
        // return `${super.speak()}, 크게 μ§–μŠ΅λ‹ˆλ‹€!`;
        return `${Animal.prototype.speak.call(this)}, 크게 μ§–μŠ΅λ‹ˆλ‹€!`;
      }
    }
    
    const dog = new Dog('뽀삐');
    console.log(dog.speak()); // "뽀삐이(κ°€) μ†Œλ¦¬λ₯Ό λƒ…λ‹ˆλ‹€, 멍멍!"
    console.log(dog.bark());  // "뽀삐이(κ°€) μ†Œλ¦¬λ₯Ό λƒ…λ‹ˆλ‹€, 크게 μ§–μŠ΅λ‹ˆλ‹€!"

    클래슀의 speak λ©”μ„œλ“œλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„κ³Ό λ™μΌν•˜κ²Œ μ·¨κΈ‰λ˜μ–΄ [[HomeObject]] μŠ¬λ‘―μ„ κ°€μ§€λ©°, λ”°λΌμ„œ superλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 반면 클래슀 ν•„λ“œμ— ν• λ‹Ήλœ 일반 ν•¨μˆ˜ barkλŠ” [[HomeObject]] 슬둯이 μ—†μ–΄ superλ₯Ό μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

    싀무적 ν•¨μ˜

    μ΄λŸ¬ν•œ κ΅¬λΆ„μ˜ 싀무적 ν•¨μ˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

    1. λ©”μ„œλ“œ μ •μ˜ μ‹œ 일관성: κ°μ²΄λ‚˜ ν΄λž˜μŠ€μ—μ„œ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  λ•ŒλŠ” μΌκ΄€λ˜κ²Œ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μ„ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μ΄λŠ” super의 μ‚¬μš© κ°€λŠ₯성을 보μž₯ν•˜κ³ , μ½”λ“œμ˜ 일관성을 μœ μ§€ν•©λ‹ˆλ‹€.
    2. 상속 κ΄€κ³„μ—μ„œμ˜ λͺ…ν™•μ„±: 상속 κ΄€κ³„μ—μ„œ λΆ€λͺ¨ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•  λ•ŒλŠ” superλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 더 λͺ…ν™•ν•˜κ³  κ°„κ²°ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄μ„œλŠ” λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    3. μ½”λ“œ μ΅œμ ν™”: μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λ₯Ό μ΅œμ ν™”ν•  수 μžˆλŠ” μ—¬μ§€κ°€ 더 λ§ŽμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ μ„±λŠ₯ μΈ‘λ©΄μ—μ„œλ„ λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μ„ μ„ ν˜Έν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

    μš”μ•½

    ES6μ—μ„œ λ©”μ„œλ“œμ™€ 일반 ν•¨μˆ˜ ν”„λ‘œνΌν‹°μ˜ ꡬ뢄은 λ‹¨μˆœν•œ 문법적 차이λ₯Ό λ„˜μ–΄, super ν‚€μ›Œλ“œμ˜ μ‚¬μš©κ³Ό 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°μ˜ 핡심 κ°œλ…μΈ 상속을 더 효과적으둜 μ§€μ›ν•˜κΈ° μœ„ν•œ μ€‘μš”ν•œ λ³€ν™”μž…λ‹ˆλ‹€. λ©”μ„œλ“œ μΆ•μ•½ ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λŠ” [[HomeObject]] λ‚΄λΆ€ μŠ¬λ‘―μ„ 톡해 μžμ‹ μ΄ μ†ν•œ 객체λ₯Ό μ•Œκ³  μžˆμ–΄, super μ°Έμ‘°λ₯Ό μ˜¬λ°”λ₯΄κ²Œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ ꡬ뢄을 μ΄ν•΄ν•˜κ³  적절히 ν™œμš©ν•˜λ©΄ 더 λͺ…ν™•ν•˜κ³  효율적인 객체 μ§€ν–₯ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Quiz) μƒμ„±μž ν•¨μˆ˜λ₯Ό 일반 ν•¨μˆ˜μ²˜λŸΌ ν˜ΈμΆœν•˜λ©΄ λ°œμƒν•˜λŠ” 일, 이λ₯Ό λ§‰κΈ°μœ„ν•œ 방법 2κ°€μ§€ 정도