super vs 프로토타입 체인

    728x90
    반응형
    SMALL

    super vs 프로토타입 체인

    객체나 클래스에서 상속을 다룰 때 헷갈리기 쉬운 두 가지 개념을 정리합니다.

    프로토타입 체인 - 끝까지 탐색

    일반적인 프로퍼티/메서드 접근은 프로토타입 체인을 따라 끝까지 올라갑니다.

    const grandParent = {
      grand() {
        return 'grand';
      }
    };
    
    const parent = {
      __proto__: grandParent,
      parent() {
        return 'parent';
      }
    };
    
    const child = {
      __proto__: parent,
      child() {
        return 'child';
      }
    };
    
    // 프로토타입 체인 탐색
    child.child();    // 'child' - child에서 찾음
    child.parent();   // 'parent' - parent까지 올라감
    child.grand();    // 'grand' - grandParent까지 올라감
    child.toString(); // [object Object] - Object.prototype까지 올라감
    

    탐색 순서:

    child → parent → grandParent → Object.prototype → null
    

     

    super - 직접 부모만 참조

    super는 자신이 정의된 객체의 직접적인 부모 객체만 참조합니다.

    const grandParent = {
      greet() {
        return 'GrandParent';
      }
    };
    
    const parent = {
      __proto__: grandParent,
      greet() {
        return 'Parent';
      }
    };
    
    const child = {
      __proto__: parent,
      
      greet() {
        return super.greet();  // parent의 greet만 호출
      }
    };
    
    child.greet();  // 'Parent' (grandParent 건너뜀)
    

    클래스에서 비교

    class GrandParent {
      greet() {
        return 'GrandParent';
      }
    }
    
    class Parent extends GrandParent {
      greet() {
        return 'Parent';
      }
    }
    
    class Child extends Parent {
      greet() {
        // super는 Parent만 참조
        return super.greet();
      }
      
      callGrandParent() {
        // GrandParent를 직접 호출할 방법 없음
        // super는 항상 직접 부모(Parent)만 참조
      }
    }
    
    const child = new Child();
    child.greet();  // 'Parent'
    

    super 체인 - 각 단계에서 호출

    class GrandParent {
      greet() {
        return 'GrandParent';
      }
    }
    
    class Parent extends GrandParent {
      greet() {
        return super.greet() + ' → Parent';
      }
    }
    
    class Child extends Parent {
      greet() {
        return super.greet() + ' → Child';
      }
    }
    
    const child = new Child();
    child.greet();
    // 'GrandParent → Parent → Child'
    
    // 동작 과정:
    // 1. Child의 greet 실행
    // 2. super.greet() → Parent의 greet 호출
    // 3. Parent의 super.greet() → GrandParent의 greet 호출
    // 4. 결과를 역순으로 조합
    

    super의 내부 동작

    const parent = {
      value: 'parent'
    };
    
    const child = {
      __proto__: parent,
      
      getValue() {
        // super의 동작:
        // 1. [[HomeObject]] = child (자신이 정의된 객체)
        // 2. [[HomeObject]]의 __proto__ = parent
        // 3. parent에서 value 찾기
        return super.value;
      }
    };
    
    child.getValue();  // 'parent'
    

    비교 예시

    class A {
      method() { return 'A'; }
    }
    
    class B extends A {
      method() { return 'B'; }
    }
    
    class C extends B {
      // 프로토타입 체인 사용
      useThis() {
        return this.method();  // 'C' (자신부터 탐색)
      }
      
      // super 사용
      useSuper() {
        return super.method();  // 'B' (직접 부모만)
      }
      
      method() { return 'C'; }
    }
    
    const c = new C();
    c.useThis();   // 'C'
    c.useSuper();  // 'B'
    

    핵심 정리

      프로토타입 체인 super
    탐색 범위 끝까지 (Object.prototype) 직접 부모만
    사용 this.method(), obj.property super.method()
    목적 자동 상속 탐색 명시적 부모 메서드 호출
    class Child extends Parent {
      method() {
        this.something();   // 프로토타입 체인 - 끝까지 탐색
        super.something();  // super - Parent만 참조
      }
    }
    

    기억하기:

    • 프로토타입 체인: 엘리베이터 🛗 (찾을 때까지 계속 올라감)
    • super: 바로 윗층 🪜 (한 단계만 올라감)
    728x90
    반응형
    LIST

    댓글