JS 클래스 상속 시 'this' 오류 해결! super()와 바인딩 문제 집중 분석

2025-10-02

친절하고 쉽게 이해하실 수 있도록, Classes 사용 시 자주 발생하는 문제와 대체 방법(ES5 문법 등)을 한국어로 설명해 드릴게요.

class 문법은 사실 자바스크립트의 프로토타입(Prototype) 기반 상속을 조금 더 익숙한 객체 지향 문법처럼 보이도록 하는 "문법적 설탕(Syntactic Sugar)"입니다. 그래서 이 특징 때문에 종종 헷갈리는 문제가 발생합니다.

클래스 상속 시, 자식 클래스(extends로 상속받은 클래스)의 constructor에서는 반드시 부모 클래스의 constructor를 호출하는 super()를 가장 먼저 호출해야 합니다.

문제 상황해결 방법
자식 클래스 constructor 내에서 super()를 호출하기 전에 this를 사용하려고 할 때 오류가 발생해요.constructor의 첫 줄에서 super()를 호출해 부모 클래스의 초기화를 완료하고, 그 다음에 this를 사용해 자식 클래스의 속성을 초기화해야 합니다.
class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child extends Parent {
  constructor(name, age) {
    //  오류 발생 지점: super()를 호출하기 전에 this를 사용하려고 했어요.
    // console.log(this.name); 
    
    super(name); //  해결책: 부모 클래스 생성자 호출은 항상 가장 먼저!
    this.age = age; 
  }
}

// const kid = new Child('철수', 10); // 주석을 풀면 오류가 발생할 수 있습니다.

클래스의 메서드(method)를 추출하여 별도의 변수에 저장하거나, 다른 곳(예 이벤트 리스너)에 콜백 함수로 전달할 때, this의 값이 원래 의도와 다르게 바인딩되어 undefined가 될 수 있습니다. 이는 클래스 메서드가 일반 함수처럼 동작하기 때문입니다.

문제 상황해결 방법
클래스 외부로 메서드를 전달했더니, 메서드 내부의 this가 클래스 인스턴스가 아닌 다른 것을 가리키거나 undefined가 됩니다.constructor에서 bind(this) 사용 화살표 함수(Arrow Function)를 클래스 속성으로 사용 (가장 흔하게 사용)
class Counter {
  constructor() {
    this.count = 0;
    //  해결책 1: bind 사용
    // this.increment = this.increment.bind(this);
  }

  //  해결책 2: 화살표 함수로 속성을 정의 (가장 권장)
  // 화살표 함수는 선언될 때 this를 상속받기 때문에 바인딩 문제가 없어요.
  increment = () => { 
    this.count++;
    console.log(this.count);
  }
  
  // 일반 메서드
  /*
  increment() {
    this.count++;
    console.log(this.count);
  }
  */
}

const counter = new Counter();
// 버튼 클릭을 흉내 내기 위해 메서드를 따로 변수에 저장합니다.
const func = counter.increment; 

// func() 호출 시, 일반 함수처럼 호출되지만, 
// 화살표 함수로 정의했기 때문에 this가 'counter' 인스턴스를 유지합니다.
func(); // 1
func(); // 2

class 문법을 사용하지 않고, 기존의 ES5 프로토타입 기반 상속 문법으로 동일한 기능을 구현할 수 있습니다. 이 방법을 알면 자바스크립트의 원리를 더 깊이 이해하는 데 도움이 됩니다.

classconstructor는 생성자 함수로, class 내의 메서드는 프로토타입으로 대체됩니다.

// 클래스(Class) 대체: 생성자 함수 (Constructor Function)
function Person(name, age) {
  // constructor 내부의 속성 정의와 동일
  this.name = name;
  this.age = age;
}

// 클래스 내부의 메서드 대체: prototype에 추가
Person.prototype.greet = function() {
  console.log(`안녕하세요, ${this.name}입니다.`);
};

const person1 = new Person('민수', 25);
person1.greet(); // 안녕하세요, 민수입니다.

extends 키워드 없이 Object.create()와 생성자 함수 호출을 이용해 상속을 구현합니다.

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

Animal.prototype.speak = function() {
  console.log(`${this.name}가 소리를 내요.`);
};

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

//  extends 대체: 프로토타입 상속
// Animal의 프로토타입을 상속받은 새 객체를 Dog의 프로토타입으로 설정
Dog.prototype = Object.create(Animal.prototype); 
// Dog.prototype.constructor를 Dog로 재설정 (필수)
Dog.prototype.constructor = Dog; 

// 자식 클래스만의 메서드 추가
Dog.prototype.bark = function() {
  console.log('멍! 멍!');
};

const myDog = new Dog('바둑이', '진돗개');
myDog.speak(); // 바둑이가 소리를 내요. (부모 메서드)
myDog.bark();  // 멍! 멍! (자식 메서드)

javascript



Temporal.PlainTime.compare 사용법 완벽 가이드: 흔한 오류와 레거시 대처법

Temporal. PlainTime. compare(time1, time2)는 두 개의 "벽시계 시간"(날짜나 시간대가 없는 순수한 시간)을 비교해서, 어느 쪽이 앞서거나 뒤처지는지를 숫자로 알려주는 메서드예요.time1이 time2보다 앞설 때 (더 이를 때) −1


JavaScript 오류 시리즈: RangeError 발생 상황별 대체 코드는?

RangeError는 JavaScript에서 어떤 값이 허용된 범위를 벗어났을 때 발생하는 오류(Error)의 한 종류예요. 이름 그대로 '범위(Range)'에 문제가 생겼다는 뜻이죠.이 오류는 주로 다음과 같은 경우에 발생할 수 있어요


알아두면 유용한 JS 에러: Private double initialization 발생 원인과 안전한 객체 생성 방법

이 에러는 정식 명칭이 TypeError: Initializing an object twice is an error with private fields/methods 입니다.클래스를 사용하여 객체를 생성할 때, 클래스 안에 비공개 필드(Private Field



JavaScript Proxy: 'set' 트랩, true를 잊지 마세요! (TypeError 방지)

이 set 트랩을 사용할 때 자주 발생하는 문제점과, 이를 해결하거나 대체할 수 있는 깔끔한 방법들을 친절하고 쉽게 설명해 드릴게요.handler. set(target, prop, value, receiver) 메서드는 프록시 객체의 속성에 값을 할당하려고 할 때(예 proxy


자바스크립트 __defineGetter__의 문제점과 Object.defineProperty, get 키워드 대체 예시

$\text{Object. __defineGetter__}$ 메서드는 객체의 특정 속성(property)에 접근할 때마다 실행되는 함수(getter)를 정의하는 데 사용되었습니다. 즉, 이 속성을 마치 일반 변수처럼 읽으려 하면


[JS 수학] Math.LN10 완벽 분석: 문제점 및 Math.log10() 대체 코드

Math. LN10은 JavaScript의 Math 객체에 있는 정적 속성(Static property) 중 하나예요. 이 값은 수학 상수 ln(10) (자연로그 loge​(10))을 나타냅니다.값 약 302585092994046


NaN, 객체 비교까지! JavaScript 동등 연산자 헷갈림 방지 가이드

자바스크립트에는 크게 두 가지 동등 연산자가 있어요.느슨한 동등 연산자 (Loose Equality Operator) == (등호 두 개)엄격한 동등 연산자 (Strict Equality Operator) === (등호 세 개)


Map.prototype.size 속성 마스터하기: 자바스크립트 컬렉션 크기 관리 팁

Map. prototype. size는 JavaScript의 Map 객체에 저장된 키-값 쌍(항목)의 개수를 반환하는 접근자 속성(accessor property)입니다. 배열의 length와 같은 역할이지만, Map의 고유한 속성이에요


자바스크립트 Map에서 값 지우기: delete()가 false를 반환하는 이유와 해결책

Map. delete(key) 메서드는 주어진 key와 일치하는 키를 가진 요소를 Map 객체에서 제거합니다.반환 값 요소가 성공적으로 제거되면 true를 반환하고, Map에 해당 키가 없어서 아무것도 제거하지 못하면 false를 반환해요


Temporal.PlainDate.toLocaleString: 흔한 문제점과 깔끔한 해결책

Temporal. PlainDate. toLocaleString()은 Intl. DateTimeFormat을 사용하여 지역화된 문자열을 생성합니다. 편리하지만 몇 가지 유의할 점이 있습니다.가장 큰 문제점은 아직 Temporal API 자체가 모든 브라우저나 Node