JavaScript 함수 상속과 클래스 상속의 차이점

1. 문법적 차이점

함수 상속 (프로토타입 체인 + 생성자 조합

함수 상속은 함수와 프로토타입을 활용하여 객체지향 상속을 구현하는 전통적인 방식입니다. 자바스크립트의 프로토타입 체인 메커니즘을 직접 활용하여 부모 객체의 메서드를 자식 객체가 상속받을 수 있도록 합니다. 구현 원리: 생성자 함수를 통해 객체를 생성하고, 프로토타입을 통해 메서드를 공유합니다. 속성은 생성자 내부에서 정의하고, 메서드는 프로토타입에 추가하여 메모리를 효율적으로 사용합니다.
// 부모 생성자
function Vehicle(model) {
  this.model = model;
}

// 프로토타입에 메서드 정의
Vehicle.prototype.drive = function() {
  return `${this.model}이(가) 주행 중입니다.`;
};

// 자식 생성자
function Car(model, doorCount) {
  // 부모 생성자 호출하여 속성 상속
  Vehicle.call(this, model);
  this.doorCount = doorCount;
}

// 프로토타입 체인 연결
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.constructor = Car;

// 자식 클래스 고유 메서드
Car.prototype.honk = function() {
  return `${this.model}이(가) 경적을 울립니다.`;
};

const myCar = new Car("Tesla", 4);
console.log(myCar.drive()); // "Tesla이(가) 주행 중입니다."
console.log(myCar.honk());  // "Tesla이(가) 경적을 울립니다."

클래스 상속 (ES6)

ES6에서 도입된 클래스 문법은 기존 프로토타입 기반 상속을 더 명확하고 직관적인 문법으로 감싸았습니다. extends 키워드를 사용하여 상속 관계를 명시적으로 표현합니다. 구현 원리: 클래스는 프로토타입 기반 상속의 문법적 설탕(syntactic sugar)입니다. 내부적으로는 여전히 프로토타입 체인을 사용하지만, 개발자는 더 깔끔한 문법으로 코드를 작성할 수 있습니다.
// 부모 클래스
class Vehicle {
  constructor(model) {
    this.model = model;
  }

  drive() {
    return `${this.model}이(가) 주행 중입니다.`;
  }
}

// 자식 클래스
class Car extends Vehicle {
  constructor(model, doorCount) {
    super(model); // 부모 클래스 생성자 호출
    this.doorCount = doorCount;
  }

  honk() {
    return `${this.model}이(가) 경적을 울립니다.`;
  }
}

const myCar = new Car("Tesla", 4);
console.log(myCar.drive()); // "Tesla이(가)주행 중입니다."
console.log(myCar.honk());  // "Tesla이(가) 경적을 울립니다."
핵심 차이: 함수 상속은 프로토타입 체인과 call/apply를 직접 조작해야 하지만, 클래스 상속은 extends와 super 키워드로 상속 관계를 간단히 표현할 수 있습니다.

2. 내부 구현 메커니즘

함수 상속의 구현 방식: - 프로토타입 체인: 생성자의 prototype 속성을 직접 수정하여 부모 메서드 상속 - 생성자 빌림: call() 또는 apply()를 사용하여 부모 생성자 실행 - 조합 상속: 프로토타입 체인과 생성자 호출을 결합하여 속성과 메서드 모두 상속 클래스 상속의 구현 방식: - 문법적 설탕: 클래스는 실제 함수로 변환되어 프로토타입 기반으로 동작 - extends 키워드: 자식 클래스의 프로토타입을 자동으로 부모 클래스에 연결 - super 키워드: 부모 클래스의 생성자나 메서드를 명시적으로 호출

3. 부모 메서드 호출 방식

함수 상속에서 부모 메서드 호출:
// 자식 프로토타입에서 부모 메서드 수동 호출
Car.prototype.driveFaster = function() {
  const baseDrive = Vehicle.prototype.drive.call(this);
  return `${baseDrive} 빠르게行驶합니다!`;
};
클래스 상속에서 부모 메서드 호출:
class Car extends Vehicle {
  driveFaster() {
    const baseDrive = super.drive();
    return `${baseDrive} 빠르게 주행합니다!`;
  }
}
비고: 클래스 상속에서는 super 키워드를 통해 부모 메서드를 간단하게 호출할 수 있지만, 함수 상속에서는 프로토타입을 직접 참조하고 call()을 사용해야 합니다.

4. 실제 사용 시나리오

함수 상속이 적합한 경우: - 레거시 프로젝트 유지보수 - ES5 호환성이 필요한 환경 - 프로토타입 체인을 세밀하게 제어해야 하는 상황 클래스 상속이 적합한 경우: - 현대적인 자바스크립트 프로젝트 - 가독성과 유지보수성이 중요한 코드베이스 - ES6 이상 환경

5. 비교 요약

구분 함수 상속 클래스 상속
문법 복잡도 높음 - 프로토타입 수동 관리 낮음 - 키워드로 간소화
코드 가독성 중간 - 프로토타입 조작 복잡 높음 - 구조 명확
브라우저 지원 모든 환경 ES6+ 또는 트랜스파일 필요
유연성 높음 - 커스터마이징 자유로움 보통 - 클래스 문법 제약
성능 유사 유사
결론: modern 자바스크립트 개발에서는 클래스 상속을 사용하는 것이 일반적입니다. 그러나 함수 상속의 원리를 이해하는 것은 자바스크립트의 프로토타입 체인 메커니즘을 파악하는 데 필수적입니다.

태그: JavaScript Prototype Class Inheritance ES6

7월 21일 20:21에 게시됨