[240405] 24장 클래스 (2)
24장 클래스 (2)
클래스의 인스턴스 생성 과정
- 인스턴스 생성과 this 바인딩
- constructor 의 내부 코드가 실행되기전에 암묵적으로 빈 객체 생성 (클래스가 생성한 인스턴스임)
- 인스턴스의 프로토타입으로 클래스의 prototype 프로퍼티가 가리키는 객체가 설정
- 인스턴스는 암묵적으로 this 에 바인딩 된다.
- constructor 내부의 this는 클래스가 생성한 인스턴스 가리킴
- 인스턴스 초기화
- this에 바인딩 되어 있는 인스턴스 초기화
- 프로퍼티를 추가하고 constructor가 인수로 전달받은 초기값으로 인스턴스의 프로퍼티 값을 초기화
- 만약 constructor가 생략되었다면 이 과정도 생략
- 인스턴스 반환
- 클래스의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this 가 암묵적으로 반환됨
class Person {
// 생성자
constructor(name) {
// 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
console.log(this); // Person {}
console.log(Object.grtPrototypeOf(this) === Person.prototype); // true
// 2. this에 바인딩되어 있는 인스턴스를 초기화
this.name = name;
// 3. 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환
}
}
프로퍼티
1. 인스턴스 프로퍼티
- constructor 내부에서 정의해야함
- 이미 인스턴스가 생성되고 this 에 바인딩 되어있음
2. 접근자 프로퍼티
- 자체적으로 값 [[Value]] 을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티
- 클래스의 메서드는 기본적으로 프로토타입 메서드 → 클래스 접근자 프로퍼티 또한 프로토타입의 프로퍼티가 됨
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// getter 함수, 접근자 프로퍼티
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
// setter 함수
set fullName() {
[this.firstName, this.lastName] = name.split(' ');
}
}
3. 클래스 필드 정의 제안
- 자바스크립트 클래스 몸체에는 메서드만 선언 가능했지만, 최신 브라우저에서는 정상 동작을 한다. (Chrome 72이상, Node.js 12이상)
- ECMA 사양 관리하는 기술 위원회도 여럿인데 ECMA-262 사양을 관리를 담당하는 위원회가 TC39 다. 여기서 제안되어있음
class Person {
// 클래스 필드 정의
name = 'Lee';
}
const me = new Person();
console.log(me); // Person {name: "Lee"}
- this 는 constructor 와 메서드 내에서만 유효
- 클래스 필드 참조할때 this 필수
- 클래스 필드에 함수도 가능, 화살표 함수도 가능
- 프로토타입 메서드가 아닌 인스턴스 메서드가 됨
- 권장하지 않는다.
class Person { // 클래스 필드 정의 name = 'Lee'; // 클래스 필드에 함수를 할당 getName = function () { return this.name; } // getName = () => this.Name; } const me = new Person(); console.log(me); // Person {name: "Lee", getName: f } console.log(me.getName()); // Lee
4. private 필드 정의 제안
class Person {
// private 필드 정의
// 반드시 몸체에 정의해야 함
#name = '';
constructor(name) {
this.#name = name;
}
}
const me = new Person('Lee');
// 외부에서는 참조할 수 없다.
console.log(me.#name); // SyntaxError
- TS에서는 public private protected 모두 지원
5. static 필드 정의 제안
class MyMath {
// static public 필드 정의
static PI = 22/7;
}
상속에 의한 클래스 확장
1. 클래스 상속과 생성자 함수 상속
- 클래스의 상속이란? 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의
- 프로토타입 기반의 상속은 프로토타입 체인을 통해 다른 객체의 자산을 상속 받는 것
2. extends 키워드
class Animal {}
// extends 키워드를 통해 상속
class Bird extends Animal {
fly() { return 'fly'; }
}
- 수퍼클래스와 서브클래스는 인스턴스 프로토타입 체인 뿐 아니라 클래스 간의 프로토타입 체인도 생성한다.
3. 동적 상속
- 생성자 함수를 상속 받아 클래스 확장도 가능
- [[Construct]] 내부 메서드를 갖는 함수 객체로 평가될 수 있는 모든 표현식 사용 가능
// 생성자 함수
function Base() {}
class Derived extends Base{}
function Base1() {}
class Base2 {}
let condition = true;
// 조건에 따라 동적으로 상속 대상을 결정하는 서브클래스
class Derived extends (condition ? Base1 : Base2) {}
4. 서브클래스의 constructor
class Base {}
class Derived extends Base {
// 생략하면 암묵적으로 정의됨
constructor(..args) { super(...args); }
}
5. super 키워드
- this 와 같이 특수한 키워드임
- super 를 호출하면 수퍼클래스의 constructor 를 호출
- super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다.
주의사항
- 서브클래스에서 constructor 를 생략하지 않은 경우 반드시 super 호출해야한다.
- 서브클래스 constructor 에서 super 를 호출하기 전에는 this 를 참조할 수 없다.
- super 는 서브클래스의 constructor 에서만 호출 된다.
super 참조
- 서브클래스 프로토타입 메서드 내에서 super.sayHi 는 수퍼클래스의 프로토타입 메서드 sayHi를 가리킨다.
- 메서드는 [[HomeObject]] 내부슬롯을 가짐
- 자신을 바인딩하고 있는 객체를 가리킴
- 메서드 축약 표현으로 정의된 함수만이 갖고 있음
const obj = {
// foo 는 ES6의 메서드 축약 표현으로 정의한 메서드
// HomeObject를 갖는다.
foo() {} ,
// 일반함수이므로 갖고 있지 않음
bar: function () {}
}
- 메서드 축약 표현으로 정의된 함수는 super 사용 가능
const base = {
name: 'Lee',
sayHi() {
return `Hi! ${this.name}`;
}
};
const derived = {
__proto__: base,
sayHi() {
return `${super.sayHi()}`;
}
};
6. 상속 클래스의 인스턴스 생성 과정
- 서브 클래스의 super 호출
- 수퍼, 서브 클래스 구별하기 위해 [[ConstructorKind]] 갖는다. 상속 안받으면 “base 설정” 받으면 받은걸로 설정
- 서브클래스는 자신이 직접 인스턴스를 생성하지 않고 수퍼클래스에게 인스턴스 생성을 위임한다. 이게 바로 서브 클래스의 constructor 에서 super를 호출해야하는 이유다.
- 수퍼클래스의 인스턴스 생성과 this 바인딩
- 암묵적으로 빈 객체 생성 (클래스 인스턴스)
- this 바인딩
- —> 수퍼클래스가 생성함
- new.target은 서브 클래스 가리킴 , 생성된건 얘가 생성됨
- 수퍼클래스의 인스턴스 초기화
- 서브 클래스 constructor 복귀과 this 바인딩
- 별도의 인스턴스 생성하지 않고 super 가 반환한 인스턴스를 this 에 바인딩함
- 서브클래스의 인스턴스 초기화
- 인스턴스 반환
7. 표준 빌트인 생성자 함수 확장
- [[Construct]] 내부 메서드를 갖는 함수 객체로 평가 가능한 표현식도 extends 사용 가능
- 빌드인 객체도 사용 가능
class MyArray extends Array {}
Leave a comment