자바스크립트는 프로토타입 기반 언어라 '상속' 개념이 존재 하지 았는데 다른 언어의 class와 비슷하게 동작하게 하는 'class'문법이 ES6에 추가 됐다.
1 클래스와 인스턴스의 개념 이해
2 자바스크립트의 클래스
3 클래스 상속
3-1 기본 구현
3-2 클래스가 구체적인 데이터를 지나지 않게 하는 방법
3-3 constructor 복구 하기
3-4 상위 클래스에 접근 수단 제공
4 ES6의 클래스 및 클래스 상속
1 클래스와 인스턴스의 개념 이해
-
클래스
- 공통 속성, 기능 정의한 추상적 개념
- 클래스를 바탕으로 인스턴스를 만들 때 비로소 어떤 객체가 클래스의 속성을 지닌다.
- 어떤 인스턴스가 다양한 클래스에 속할 수는 있지만 이 클래스들은 모두 인스턴스 입장에서는 '직계존속'
- 다중상속을 지원하는 언어이든 그렇지 않은 언어이든 결국 인스턴스를 생성할 때 호출할 수 있는 클래스는 오직 하나뿐일 수 밖에 없기 때문
-
인스턴스
- 클래스에 속한 객체
-
static member(static method, static properties)
- 클래스 자체에서만 동작
-
prorotype method
- 인스턴스에서 활용 가능
2 자바스크립트의 클래스
-
생성자 함수 Array를 new연선자와 함께 호출하면 인스턴스 생성 하는 과정을 통한 설명
- Array를 일종의 클래스라고 하면, Array의 prototype 객체 내부 요소들이 인스턴스에 '상속'된다고 볼 수 있다.
- 엄밀하게 상속이 아닌 프로토타입 체이닝에 의한 참조지만 결과적으로 동일하게 동작
- 한편 Array 내부 프로퍼티들 중 prorotype 프로퍼티를 제외한 나머지 인스턴스에 상속되지 않는다.
(=== static member: static method, static properties) - 인스턴스에 상속되는지(인스턴스가 참조하는지) 여부에 따라 "static member"(상속불가능)와 "instance member"(상속가능)로 나뉜다.
- 이 분류는 다른 언어의 클래스 구성요소에 대한 정의를 차용한것으로 클래스 입장에서 사용대상에 따라 구분한것
- 하지만 자바스크립트는 다른 언어와 달리 인스턴스에서도 직접 메서드를 정의할 수 있다.
- 그래서 '인스턴스 메서드'라는 명칭은 프로토타입에 정의한 메서드를 지칭하는 것인지 인스턴스에 정의한 메서드를 지칭하는것인지 혼란이 올 수 있다.
따라서 프로토타입에 정의한 메서드를 프로토타입 메서드라고 부른다. - 도식화 - Array constructor function
- 도식화 - prorotype, __proto__, instance
- 실제 예제
function Person(name, age) {
this._name = name
this._age = age
}
Person.getInformations = function(inst) {
//Static emthod
return {
name: inst._name,
age: inst._age,
}
}
Person.prototype.getName = function() {
//(prototype) method
return this._name
}
Person.prototype.getAge = function() {
//(prototype) method
return this._age
}
var yoon = new Person("happyjy", 30)
console.log(yoon.getName()) //happyjy
console.log(yoon.getAge()) //30
console.log(yoon.getInformations(yoon))
//에러! yoon.getInformations is not a function
//생성자 함수 property(getInformations)에는 인스턴스가 직접 접근하지 못한다.
//생성자 함수 property는 인스턴스로 상속할 수 있는 프로퍼티로 만들지 않는다.
console.log(Person.getInformations(yoon)) //{name: "happyjy", age: "30"}
//생성자 함수 property는 생성자 함수로만 접근이 가능하다.
3 클래스 상속
3-1 기본 구현
-
구현 point
- 프로토타입 설정
- contsructor 복구
function Person(name, age) { this.name = name || "홍길동" this.age = age || 0 } Person.prototype.getName = function() { return this.name } Person.prototype.getAge = function() { return this.age } function Employee(name, age, position) { this.name = name || "홍길동(setting by Employee function)" this.age = age || 0 this.position = position || "미정" } //1.prorotype 설정 Employee.prototype = new Person() // 이 코드에 의해서 new Employee에 의해서 생성된 인스턴스.__proto__에 Person 인스턴가 세팅된다. //2. constructor 복구 Employee.prototype.constructor = Employee // prototype에서 다뤘던 내용 Employee.prototype.getPosition = function() { return this.position } var mac = new Employee("mac", 30, "CTO")
-
mac의 결과 값
- 문제: mac.\_proto__에 추상적이어야할 클래스 prorotype 담겨 있는 것_
- 만약 delete mac.name이후 mac.getName을 하면 undefined가 return 되어야 하는데 prototype chain에 의해서 홍길동(mac.proto property)이 반환된다.
- 그래서 아래 예제 "prototype"로 상속 구현하기에 extendClass에 의해서 문제를 해결할 수 있다.
- 문제 해결 방법 요약: 상속할때 parent, child class 사이에서 extend해주는 개념이 필요하다
: 아래 3-2, 3-3, 3-4 capter에서 다루도록 하겠다.
3-2 클래스가 구체적인 데이터를 지나지 않게 하는 방법
- 아래 도식화(extend Class 구현 개념)에서 빨간색 동그라미 1,2번 참고
3-3 constructor 복구 하기
- 아래 도식화(extend Class 구현 개념)에서 빨간색 동그라미 3번 참고
3-4 상위 클래스에 접근 수단 제공
- 아래 도식화(extend Class 구현 개념)에서 빨간색 동그라미 4번 참고
- extend Class 구현 개념 - 아래 구현 예제 주석 1,2,3,4번 코드 참고
-
extendClass구현으로 prototype상속 구현
//* es5에서 많이 사용해서 아래와 같이 클래스 상속을 구현 //* 클로저를 생성해서 'Bridge'를 단한번만 사용할 수 있게 함 var extendClass = (function() { function Bridge() {} return function(Parent, Child) { Bridge.prototype = Parent.prorotype //1번 Child.prototype = new Bridge() //2번 Child.prototype.constructor = Child //3번 Child.prototype.superClass = Parent //4번 } })() function Person(name, age) { this.name = name || "홍길동" this.age = age || 0 } Person.prototype.getName = function() { return this.name } Person.prototype.getAge = function() { return this.age } function Employee(name, age, position) { this.superClass(name, age) //4번: 하위 클래스에서 이런 호출로 상위 클래스가 설정한 프로퍼티 세팅 가능 this.position = position || "미정" } extendClass(Person, Employee) Employee.prototype.getPosition = function() { return this.position } var mac = new Employee("mac", 30, "CTO")
- 결과
-
짚고 넘어가자! - this.superClass에 대해서
- this.superClass는 Parent object이기 때문에 Person constructor function에서 name, age설정
- Person constructor function에서 this.name, this.age에 설정 시 this scope은 "Employee instance object"라서 위 결과 처럼 name, age가 Employee instance property에 설정 된다.
4 ES6의 클래스 및 클래스 상속
- class로 상속 구현하기
class Person {
constructor(name, age) {
this.name = name || "아무개"
this.age = age || "0"
}
getName() {
return this.name
}
getAge() {
return this.age
}
}
class Employee extends Person {
constructor(name, age, position) {
super(name, age)
this.position = position || "미정"
}
getPosition() {
return this.position
}
}
참고
- 코어 자바스크립트