1. 클래스와 인스턴스의 개념 이해
자바스크립트는 프로토타입 기반 언어라서 '상속'의 개념이 존재하지 않습니다.
ES6에서 클래스 문법이 추가되었는데 일정 부분 프로토타입을 활용하기 때문에 ES5의 클래스를 흉내내기 위한 구현방식을 학습해두어야 합니다.
음식은 과일보다 상위의 개념이고, 과일은 음식보다 하위의 개념입니다.
이를 상위 클래스 (superclass)/하위 클래스 (subclass)로 표현합니다.
인스턴스란?
위의 예제처럼 감귤, 자몽, 천혜향처럼 클래스의 속성을 띠는 구체적인 개체를 인스턴스라고 합니다.
쉽게 말하자면 어떤 조건에 부합하는 구체적인 예시라고 볼 수 있는데 여기서 조건을 클래스라고 본다면
어떤 클래스에 속한 개체는 해당 클래스의 조건을 모두 만족하기 때문에 그 클래스의 구체적인 예시 즉 인스턴스가 되는 것입니다.
프로그래밍 언어에서의 클래스
현실 세계에서와는 달리 사용자가 직접 클래스를 정의해야 하고, 클래스를 바탕으로 인스턴스가 생성됩니다.
클래스를 바탕으로 인스턴스를 만들 때 비로소 어떤 개체가 클래스의 속성을 지닙니다.
한 인스턴스는 하나의 클래스만을 바탕으로 만들어집니다.
다중 상속을 지원하는 언어이던 그렇지 않은 언어든 인스턴스를 생성할 때는 하나의 클래스밖에 호출하지 못합니다.
현실 세계의 클래스는 추상적인 개념이지만,
프로그래밍 언어의 클래스는 사용하기에 따라 추상적인 대상이기도 하고 구체적인 개체이기도 합니다.
2. 자바스크립트의 클래스
자바스크립트에는 클래스의 개념이 존재하지 않습니다.
따라서 프로토타입을 활용하여 클래스와 유사한 기능을 구현합니다.
- new 연산자로 생성자 함수 Array를 호출하면 인스턴스가 생성됩니다.
- 이 Array를 일종의 클래스라 하면 Array의 prototype 객체 내부 요소들이 인스턴스에 프로토타입 체이닝을 통해 '참조'되는데 이를 인스턴스에 '상속'된다고도 볼 수 있습니다.
- 이때 Array 내부 프로퍼티들 중 prototype프로퍼티만 상속되고 나머지는 상속되지 않습니다.
- 인스턴스에 상속되는지 여부에 따라 스태틱 멤버 (static member)와 인스턴스 멤버(instance member)로 나뉩니다.
>>클래스 기반 언어와는 달리 자바스크립트에서는 인스턴스에서도 직접 메서드를 정의할 수 있는데 이를 프로토타입 메서드 라고 합니다.
프로토타입 객체에 할당한 메서드는 인스턴스가 자신의 것처럼 호출할 수 있습니다.
인스턴스에서 직접 호출할 수 있는 메서드를 프로토타입 메서드라고 합니다.
또한 인스턴스에서 직접 접근할 수 없는 메서드를 스태틱 메서드 라고 합니다.
프로그래밍 언어의 클래스는 사용하기에 따라 추상적인 대상이기도 하고 구체적인 개체이기도 하다
- 구체적인 인스턴스가 사용할 메서드를 정의한 '틀'의 역할을 할 때 클래스는 '추상적인 대상' 입니다.
- 클래스 자체를 this로 해서 직접 접근해야 하는 스태틱 메서드를 호출할 때 클래스는 '구체적인 개체' 입니다.
3. 클래스 상속
7-3-1 기본 구현
객체지향에서 클래스 상속은 가장 중요한 요소입니다.
이 때문에 클래스 문법이 없던 ES5까지의 자바스크립트 사용자들은 클래스 상속을 최대한 흉내내는 것이 주요한 관심사였습니다.
이제 클래스 문법을 사용하지 않고 자바스크립트에서 클래스를 구현했던 다양한 방법들을 살펴보겠습니다.
위의 예제가 클래스 상속의 핵심입니다.
자바스크립트에서 클래스 상속을 구현했다는 것은 결국 프로토타입 체이닝을 잘 했다는 말입니다.
그러나 위 예제는 몇가지 문제가 있습니다.
length 프로퍼티가 configurabla(삭제 가능)하다는 점과 Grade.prototype이 빈 배열을 참조한다는 점입니다.
이러한 문제들을 가지고 있는 예제들처럼 클래스에 있는 값이 인스턴스의 동작에 영향을 줘서는 안됩니다.
그 자체로 클래스의 추상성을 해치는 것이기 때문입니다.
클래스는 구체적인 데이터를 가져서는 안되고 오직 인스턴스가 사용할 메서드만을 가져야 합니다.
정리
- 자바스크립트는 프로토타입 기반 언어라서 클래스 및 상속 개념은 존재하지 않지만 프로토타입을 기반으로 클래스와 비슷하게 동작하게끔 하는 다양한 기법들이 도입돼 왔습니다.
- 클래스는 어떤 사물의 공통 속성을 모아 정의한 추상적인 개념이고, 인스턴스는 클래스의 속성을 지니는 구체적인 사례입니다. 상위클래스(superclass)의 조건을 충족하면서 더욱 구체적인 조건이 추가된 것을 하위클래스(subclass)라고 합니다.
- 클래스의 prototype 내부에 정의된 메서드를 프로토타입 메서드라고 하며, 이들은 인스턴스가 마치 자신의 것처럼 호출할 수 있습니다. 한편 클래스(생성자 함수)에 직접 정의한 메서드를 스태틱 메서드라고 하며, 이들은 인스턴스가 직접 호출할 수 없고 클래스(생성자 함수)에 의해서만 호출할 수 있습니다.
- 클래스 상속을 흉내내기 위한 세 가지 방법인 SubClass.prototype에 SuperClass의 인스턴스를 할당한 다음 프로퍼티를 모두 삭제하는 방법, 빈 함수(Bridge)를 활용하는 방법, Object.create를 이용하는 방법입니다. 이 세가지 방법 모두 constructor프로퍼티가 원래의 생성자 함수를 바라보도록 조정해야 합니다.