본문 바로가기
JavaScript

[JavaScript] 프로토타입으로 상속하기

by teamnova 2024. 12. 25.
728x90

안녕하세요!

자바스크립트는 객체 지향 프로그래밍 언어로, **프로토타입 기반 상속(prototype-based inheritance)**을 지원합니다. 다른 객체 지향 언어에서 흔히 사용하는 클래스(class) 기반 상속과는 다르지만, 자바스크립트의 프로토타입 체인을 활용하면 유사한 상속 구조를 구현할 수 있습니다.

이번 글에서는 프로토타입의 개념프로토타입을 활용한 상속 구현 방법을 단계별로 알아보겠습니다.

 

1. 프로토타입이란?

자바스크립트에서 모든 객체는 숨겨진 링크인 [[Prototype]]을 가지고 있습니다. 이 링크는 객체가 다른 객체로부터 속성과 메서드를 상속받을 수 있도록 연결해주는 역할을 합니다. 이 [[Prototype]]은 __proto__로 접근할 수 있으며, 함수 객체에는 prototype이라는 속성도 존재합니다.

1.1 프로토타입 체인

프로토타입 체인은 객체의 속성이나 메서드를 찾을 때 사용됩니다. 객체에 해당 속성이나 메서드가 없으면, 프로토타입 체인을 따라 상위 객체에서 이를 찾습니다.

const obj = {
  name: 'Alice',
};

console.log(obj.toString()); // "[object Object]"

// 'toString' 메서드는 obj에 없으므로, obj의 프로토타입(Object.prototype)에서 찾음
console.log(Object.prototype.toString); // [Function: toString]

 

2. 프로토타입을 활용한 상속

프로토타입을 사용하면 객체 간에 속성과 메서드를 공유할 수 있습니다. 이를 통해 상속 구조를 구현할 수 있습니다. 아래는 프로토타입 상속을 구현하는 방법을 단계별로 설명합니다.

2.1 기본 객체 생성

먼저, 부모 객체를 생성하고, 이를 다른 객체가 상속받도록 설정합니다.

// 부모 객체 정의
const animal = {
  eat() {
    console.log('This animal is eating.');
  },
};

// 자식 객체 생성 및 상속
const dog = Object.create(animal); // animal을 프로토타입으로 설정
dog.bark = function () {
  console.log('Woof! Woof!');
};

// 메서드 호출
dog.eat(); // 부모 객체의 메서드 호출: 'This animal is eating.'
dog.bark(); // 자식 객체의 메서드 호출: 'Woof! Woof!'

 

2.2 생성자 함수와 프로토타입을 활용한 상속

생성자 함수와 프로토타입을 사용하면 더 정교한 상속 구조를 구현할 수 있습니다.

// 부모 생성자 함수
function Animal(name) {
  this.name = name;
}

// 부모 프로토타입에 메서드 정의
Animal.prototype.eat = function () {
  console.log(`${this.name} is eating.`);
};

// 자식 생성자 함수
function Dog(name, breed) {
  Animal.call(this, name); // 부모 생성자 호출
  this.breed = breed;
}

// 자식 프로토타입을 부모의 프로토타입으로 설정
Dog.prototype = Object.create(Animal.prototype);

// 자식 프로토타입에 메서드 추가
Dog.prototype.bark = function () {
  console.log(`${this.name} is barking: Woof! Woof!`);
};

// 객체 생성
const myDog = new Dog('Buddy', 'Golden Retriever');

// 메서드 호출
myDog.eat(); // 'Buddy is eating.'
myDog.bark(); // 'Buddy is barking: Woof! Woof!'

 

2.3 Object.create를 활용한 상속

Object.create는 객체를 생성하면서 프로토타입을 설정할 수 있는 강력한 도구입니다. 이를 사용하면 간단하게 상속 구조를 구현할 수 있습니다.

// 부모 객체
const animal = {
  eat() {
    console.log('This animal is eating.');
  },
};

// 자식 객체 생성
const cat = Object.create(animal);
cat.meow = function () {
  console.log('Meow!');
};

// 메서드 호출
cat.eat(); // 'This animal is eating.'
cat.meow(); // 'Meow!'

 

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

3.1 장점

  • 메모리 효율성: 상속받은 메서드는 프로토타입 체인을 통해 공유되므로, 메모리를 절약할 수 있습니다.
  • 유연성: 객체를 동적으로 생성하고, 프로토타입을 변경하여 쉽게 상속 구조를 수정할 수 있습니다.

3.2 단점

  • 디버깅 어려움: 프로토타입 체인을 따라가며 속성을 찾는 과정이 복잡해질 수 있습니다.
  • 구조의 명확성 부족: 클래스 기반 상속에 비해 구조가 덜 명확할 수 있습니다.

 

 

4. ES6 클래스와의 비교

ES6에서 도입된 클래스는 프로토타입 기반 상속을 보다 직관적으로 사용할 수 있도록 설계되었습니다. 클래스의 내부 동작은 여전히 프로토타입 체인을 사용하지만, 구문이 간결하고 가독성이 좋습니다.

class Animal {
  constructor(name) {
    this.name = name;
  }

  eat() {
    console.log(`${this.name} is eating.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 부모 클래스의 생성자 호출
    this.breed = breed;
  }

  bark() {
    console.log(`${this.name} is barking: Woof! Woof!`);
  }
}

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.eat(); // 'Buddy is eating.'
myDog.bark(); // 'Buddy is barking: Woof! Woof!'