클래스간의 상속
- 자바스크립트에서는 엄밀히 따지면 일반적인 클래스 개념이 존재하지 않지만, 편의를 위해 클래스라고 지칭함.
- 하나의 클래스에서 다른 클래스에게 프로토타입을 상속하는 것을 클래스간의 상속이라고 할 수 있다. 말그대로 기존의 클래스를 활용해 다른 클래스를 생성하면서 기존 클래스를 확장시켜 활용할 수 있는 것.
- 장점은 역시 DRY 원칙을 지킬 수 있다는 것이다. 클래스 상속 구현을 위해서 부모 클래스의 속성을 가진 자식 클래스의 속성을 직접 작성하면, 부모 클래스에서 변동사항이 생겼을 때 그것이 자식 클래스에 자동적으로 반영되지 않는다.
ES5 생성자 함수 방식에서 구현
- ES5 생성자 함수 방식에서 클래스간 연결을 위해서는...
- 먼저 프로퍼티 상속을 위해 자식 클래스 생성자 함수 내부에서 부모 클래스를 호출한다.
- 그리고 자식 클래스에 메서드를 추가하기 전에 자식 클래스의 프로토타입을 Object.create 메서드로 연결한다. (mdn에 따르면, 이 메서드는 지정된 프로토타입 객체 및 속성을 갖는 "새 객체"를 생성한다.)
// 부모 클래스
const Person = function (firstName, birthYear) {
this.firstName = firstName;
this.birthYear = birthYear;
Person.prototype.calcAge = function () {
console.log(2044 - this.birthYear);
};
};
// 자식 클래스
const Student = function (firstName, birthYear, course) {
// this 바인딩을 위해 call 메서드로 상속받을 부모 클래스를 호출한다.
Person.call(this, firstName, birthYear);
// course 라는 전달인자를 확장하여 새로운 속성을 추가한다.
this.course = course;
};
- 자식 클래스의 프로토타입을 직접 연결하기 이전, 이 자식클래스의 프로토타입 즉 상위 객체는 Obejct 이다.
- 아래 코드를 추가해 부모 클래스의 프로토타입으로 직접 연결시킨다.
Student.prototype = Object.create(Person.prototype);
- 이후 console.dir 로 자식 클래스를 확인해보면, 자식 클래스의 프로토타입 속성이 부모 클래스인 것을 확인할 수 있다.
- Object.create를 사용해서 새 객체를 만들어 할당해주는 이유는, 정상적인 프로토타입 체인을 만들기 위해서이다.
// 직접 할당해버린 경우
// 프로토타입 체인이 아닌 그냥 Person.prototype이 되어버린다.
Student.prototype = Person.prototype;
- 이렇게 부모 클래스와 연결된 자식 클래스의 프로토타입에 새로운 메서드를 추가해줄 수 있다.
Student.prototype.introduce = function () {
console.log(`제 이름은 ${this.firstName}, 제 전공은 ${this.course}.`);
};
- 추가적으로 자식 클래스 프로토타입의 constructor 프로퍼티를 부모클래스가 아닌 자기 자신이 되도록 변경한다. 프로토타입 객체는 부모 클래스로부터 생성된 것이 아니라 단지 상속받은 것이기 때문에, 원본 생성자를 가리키는 것이 맞다.
Student.prototype.constructor = Student;
- 이런 과정을 거쳐 자식 클래스 Student로 부터 mike라는 인스턴스를 생성했을 때, mike는 Student 클래스의 인스턴스이자, (상속을 받았으므로) 그 부모 클래스인 Person의 인스턴스이기도 하다.
console.log(mike instanceof Student); // true
console.log(mike instanceof Person); // true
ES6 클래스 문법 활용
- ES6 클래스 문법에서는 extends 키워드와 super() 연산자를 사용해 클래스간의 상속이 이루어질 수 있다. ES5 생성자 함수 방식과 동작 원리는 같지만 문법적으로 훨씬 더 편리하게 사용할 수 있다는 장점이 있다!
// 부모 클래스
class Person2 {
constructor(name) {
this.birthYear = 1997;
this.name = name;
}
age = function () {
return 2022 - this.birthYear;
};
}
// 자식 클래스
class Hyejung extends Person2 {
// call메서드로 부모 클래스를 호출할 필요가 없다!
constructor(name) {
// 상위 클래스 생성자를 호출해, 이 매개변수로 상위 클래스의 속성을 상속받을 수 있다.
super(name);
}
}
- 참고로 자식 클래스에서 새로운 생성자가 필요하지 않은 경우, constructor 없이 extends 로 호출해도 부모로 부터 상속된다.
SUMMARY
ES5 생성자 함수 방식 구현
- 나름대로 이해한 내용을 정리해보았는데, 과정이 복잡해서인지 명확하게 설명하기가 조금 힘들었다. 그래도 이 내용을 바탕을 요약을 해보자면..
- ES5 문법에서 한 클래스에서 다른 클래스로부터 상속을 받기 위해서는, 먼저 함수 내부에서 생성자를 호출해 그 프로퍼티를 가져와야한다. 그리고 자식 클래스의 프로토타입 프로퍼티를 부모 클래스로 부터 가져온 내용을 모두 포함하고 있는 새 객체로 재할당한 뒤, 그 곳에 새롭게 메서드를 등록해준다.
- 추가적으로 이 과정에서 자식 클래스의 프로토타입 constructor가 부모 클래스로 바뀌어있을 수 있는데, 이를 원래대로 즉 부모 클래스가 아닌 생성자 자신을 가리키도록 변경한다.
참고자료
https://www.udemy.com/course/the-complete-javascript-course
'JavaScript > JavaScript' 카테고리의 다른 글
[JavaScript] 비동기 흐름 제어 -2 : async / await 활용하기 (0) | 2022.07.28 |
---|---|
[JavaScript] 비동기 흐름 제어 -1 : 콜백함수, promise (0) | 2022.07.28 |
[JavaScript] 프로토타입 체인 (0) | 2022.07.25 |
[JavaScript] 프로토타입 (0) | 2022.07.22 |
[JavaScript] OOP in JavaScript : 생성자 함수, 클래스 문법 (0) | 2022.07.22 |