프로토타입 기반 상속

2025. 10. 12. 17:09·Frontend/Javascript Essentials

 

자바스크립트는 다른 언어(C++, Java 등)의 클래스 기반 상속(class-based inheritance)과 달리,

프로토타입 기반 상속(prototype-based inheritance)을 사용한다.

이는 객체가 다른 객체를 직접 상속받아 동작하는 방식으로, 자바스크립트의 유연한 객체 지향 특성을 잘 보여준다.

 

1. 프로토타입 기반 상속이란?

모든 객체는 내부적으로 [[Prototype]](또는 __proto__)이라는 숨겨진 참조를 가진다.

이 참조를 통해 상위 객체(프로토타입 객체)의 속성과 메서드를 공유받는다. 즉, 객체 간 직접적인 상속 관계가 형성되는 것이다.

 

ES6의 class와 extends 문법은 이러한 프로토타입 상속을 문법적으로 단순화한 표현(syntactic sugar)이다.

 

 

2. 동작 원리: 프로토타입 체이닝

  1. 객체가 어떤 속성이나 메서드를 호출하면, 자바스크립트 엔진은 먼저 자신의 프로퍼티에서 찾는다.
  2. 없다면 [[Prototype]]을 따라 상위 객체에서 같은 이름을 탐색한다.
  3. 이 과정을 프로토타입 체이닝(Prototype Chaining)이라 하며, 상위 객체에서도 찾지 못하면 최종적으로 null에서 탐색을 멈추고 undefined를 반환한다.
const obj = {};
console.log(obj.toString()); // [object Object]
// obj에는 toString이 없지만, Object.prototype에서 상속받아 사용

 

3. 프로토타입 상속의 장점

  1. 공통 기능 재사용 - 예: Array, Object, Function 등 내장 객체의 공통 메서드는 각자의 프로토타입에 정의되어, 모든 인스턴스가 이를 공유한다.
  2. 메모리 효율성 - 인스턴스마다 메서드를 복제하지 않고 공통 프로토타입을 참조하므로 메모리 낭비가 없다.
  3. 동적 확장성 - 런타임 중에도 프로토타입 체인을 변경하거나 메서드를 추가할 수 있어 매우 유연하다.

 

4. 프로토타입 상속 예제

자바스크립트는 함수가 정의될 때 자동으로 prototype 객체를 생성한다.

이 prototype 객체 안에는 constructor 속성이 있으며, 이를 통해 다시 원래 생성자 함수를 가리킨다.

 

이 구조를 이용해 상속을 구현할 수 있다.

1. 기본 구조

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function () {
  return `${this.name} makes a sound.`;
};

 

Animal은 생성자 함수다. Animal.prototype에 speak 메서드를 정의하면, 모든 Animal 인스턴스가 이를 공유한다.

const cat = new Animal('Kitty');
console.log(cat.speak()); // Kitty makes a sound.

이 시점에서 cat 객체 내부 구조는 다음과 유사하다.

cat
 ├── name: "Kitty"
 └── [[Prototype]] → Animal.prototype
                           └── speak()

즉, cat.speak()를 호출할 때

cat 자신에게 speak가 없으므로, JS 엔진은 [[Prototype]]을 따라

Animal.prototype에서 speak를 찾아 실행한다.

2. 상속 구현 (Dog → Animal)

이제 Dog가 Animal을 상속받도록 만들어보자.

function Dog(name) {
  // Animal의 생성자 호출
  Animal.call(this, name);
}

여기서 Animal.call(this, name)은 Dog 생성자 내부에서 Animal의 초기화 로직을 재사용하는 부분이다.

 

이제 프로토타입 체인을 연결해야 한다.

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Object.create(Animal.prototype) → 새로운 객체를 만들되, 그 객체의 [[Prototype]]을 Animal.prototype으로 지정한다.

Dog.prototype.constructor = Dog → 프로토타입 체인을 변경했기 때문에, constructor가 다시 Animal을 가리키는 문제를 수정한다.

3. 메서드 오버라이딩

Dog만의 메서드를 추가할 수 있다.

Dog.prototype.speak = function () {
  return `${this.name} barks.`;
};

4. 최종 예제

function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function () {
  return `${this.name} makes a sound.`;
};

function Dog(name) {
  Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function () {
  return `${this.name} barks.`;
};

const dog = new Dog('Buddy');

console.log(dog.speak()); // Buddy barks.
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true

5. 실행 흐름 정리

  1. new Dog('Buddy')를 실행하면
    • 새로운 객체가 생성되고 this로 바인딩된다.
    • Animal.call(this, name)을 통해 name 속성이 설정된다.
  2. JS 엔진은 dog.speak() 호출 시,
    • Dog.prototype에서 speak를 찾고(Buddy barks. 출력)
    • 없으면 Animal.prototype로 올라간다.
  3. 이때 dog의 내부 구조는 아래와 같다:
dog
 ├── name: "Buddy"
 └── [[Prototype]] → Dog.prototype
                           ├── speak()  // Dog의 speak
                           └── [[Prototype]] → Animal.prototype
                                                      ├── speak()
                                                      └── constructor: Animal

6. 프로토타입 체이닝의 확인

console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null

이처럼 프로토타입은 계층적으로 연결되어 있고, null에 도달하면 탐색이 종료된다.

 

5. 정리

개념 설명
상속 방식 프로토타입 기반 (객체 간 상속)
핵심 메커니즘 [[Prototype]] → 프로토타입 체이닝
장점 메모리 효율, 재사용성, 유연성
ES6 클래스 문법 프로토타입 기반 상속을 단순화한 문법적 설탕

 

'Frontend > Javascript Essentials' 카테고리의 다른 글

클로저 — 함수가 변수를 기억하는 방식  (0) 2025.10.12
이벤트 루프  (0) 2025.10.11
'Frontend/Javascript Essentials' 카테고리의 다른 글
  • 클로저 — 함수가 변수를 기억하는 방식
  • 이벤트 루프
JTB
JTB
웹/앱 개발 정보를 공유하고 있습니다.
  • JTB
    JTechBlog
    JTB
  • 전체
    오늘
    어제
    • All About Programming;) N
      • Computer Science
        • Terminology and Concepts
        • Network
        • Operating System
        • Database
        • Data Structure
      • Frontend N
        • Javascript Essentials N
        • Perfomance Optimization
        • JS Patterns
        • Next.js
        • Flutter
        • Testing
      • Backend
        • Node.js
      • DevOps
        • Docker & Kubernetes
      • Coding Test N
        • LeetCode N
        • Programmers
      • Tech Books & Lectures
        • Javascript_Modern JS Deep d..
        • Network_IT 엔지니어를 위한 네트워크 입문
      • Projects
        • PolyLingo_2025
        • Build Your Body_2024
        • JStargram_2021
        • Covid19 Tracker_2021
        • JPortfolio_2021
      • BootCamp_Codestates
        • TIL
        • TILookCloser
        • Pre Tech Blog
        • IM Tech Blog
        • Daily Issues and DeBugging
        • First Project
        • Final Project
        • Sprint Review
        • Good to Know
        • Socrative Review
        • HTML & CSS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 글쓰기
    • 관리
  • 공지사항

  • 인기 글

  • 태그

    Operating System
    커리어
    자바스크립트 딥다이브
    자바스크립트
    leetcode
    TCP/IP
    Time complexity and Space complexity
    js pattern
    Network
    Threads and Multithreading
    need a database
    testing
    딥다이브
    Data Structure
    VoiceJournal
    모던 자바스크립트 Deep Dive
    스코프
    프론트엔드 성능 최적화 가이드
    CPU scheduling algorithm
    How memory manage data
    indie hacker
    mobile app
    structure of os
    database
    polylingo
    Shared resources
    Binary Tree BFS
    이벤트
    Javascript Essentials
    DOM
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
JTB
프로토타입 기반 상속
상단으로

티스토리툴바