일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 자바스크립트 #javascript #렌더링 #렌더링순서
- 세션스토리지
- NavigationDuplicated
- VUE
- 라우터
- 렌더링 최적화
- vue.js
- lazy loading
- 안드로이드
- vue #vue.js #font #web-font
- Django
- Router
- 뷰
- css
- 장고
- 주니어 개발자
- jest
- Transition
- 세션
- 로컬스토리지
- cubic-bezier
- 예외처리
- frontend
- vuetify
- 성능 최적화
- webpack
- DOM
- vue-router
- virtual dom
- 프론트엔드
- Today
- Total
한준호
[Modern javascript] 클래스(2) 본문
■ 프로퍼티
- constructor 내부에서 정의한다.
◎ 접근자 프로퍼티
- getter / setter를 의미. 자체적인 값 [[Value]]를 갖지 않음
const person = {
// 데이터 프로퍼티
firstName: 'Ungmo',
lastName: 'Lee',
// fullName은 접근자 함수로 구성된 접근자 프로퍼티다.
// getter 함수
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
// setter 함수
set fullName(name) {
// 배열 디스트럭처링 할당: "36.1. 배열 디스트럭처링 할당" 참고
[this.firstName, this.lastName] = name.split(' ');
}
};
// 데이터 프로퍼티를 통한 프로퍼티 값의 참조.
console.log(`${person.firstName} ${person.lastName}`); // Ungmo Lee
// 접근자 프로퍼티를 통한 프로퍼티 값의 저장
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
person.fullName = 'Heegun Lee';
console.log(person); // {firstName: "Heegun", lastName: "Lee"}
// 접근자 프로퍼티를 통한 프로퍼티 값의 참조
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다.
console.log(person.fullName); // Heegun Lee
// fullName은 접근자 프로퍼티다.
// 접근자 프로퍼티는 get, set, enumerable, configurable 프로퍼티 어트리뷰트를 갖는다.
console.log(Object.getOwnPropertyDescriptor(person, 'fullName'));
// {get: ƒ, set: ƒ, enumerable: true, configurable: true}
getter와 setter는 호출하는 것이 아니라 프로퍼티처럼 참조하는 형식으로 사용된다.
클래스의 접근자 프로퍼티(getter, setter) 또한 인스턴스 프로퍼티가 아닌 프로토타입의 프로퍼티이다.
◎ 클래스 필드 정의 제안
자바와 비슷한 형식으로 클래스 내 지역 변수를 정의할 수 있다(최신 브라우저와 최신 Node.js에서만 가능)
class Person {
// 클래스 필드 정의
name = 'Lee';
}
const me = new Person();
console.log(me); // Person {name: "Lee"}
- 클래스 필드에 초기값을 할당하지 않으면 undefined 할당
- 외부의 매개변수로 클래스 필드를 초기화해야 할 필요가 있다면 constructor에서 클래스 필드를 초기화 한다.
class Person {
name;
constructor(name) {
// 클래스 필드 초기화.
this.name = name;
}
}
const me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
- 함수는 일급 객체이므로 함수를 클래스 필드에 할당할 수 있다. 이 경우 프로토타입 메서드가 아닌 인스턴스 메서드가 된다.(권장되지 않음)
class Person {
// 클래스 필드에 문자열을 할당
name = 'Lee';
// 클래스 필드에 함수를 할당
getName = function () {
return this.name;
}
// 화살표 함수로 정의할 수도 있다.
// getName = () => this.name;
}
const me = new Person();
console.log(me); // Person {name: "Lee", getName: ƒ}
console.log(me.getName()); // Lee
◎ private 필드 정의 제안
최신 브라우저, 최신 Node.js에서 사용 가능
class Person {
// private 필드 정의
#name = '';
constructor(name) {
// private 필드 참조
this.#name = name;
}
get name() {
return this.#name.trim();
}
}
const me = new Person('Lee');
// private 필드 #name은 클래스 외부에서 참조할 수 없다.
console.log(me.#name);
// SyntaxError: Private field '#name' must be declared in an enclosing class
// 접근자 프로퍼티는 접근 가능
console.log(me.name); // Lee
■ 상속에 의한 클래스 확장
- 프로토타입 기반 상속은 프로토타입 체인을 통해 다른 객체의 자산을 상속받는 것이지만, 상속에 의한 클래스 확장은 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의하는 것이다.
- 수퍼클래스와 서브클래스는 인스턴스의 프로토타입 체인뿐 아니라 클래스 간의 프로토타입 체인도 생성한다. 이를 통해 프로토타입 메서드, 정적 메서드 모두 상속이 가능하다.
- extends 키워드는 생성자 함수도 상속 가능하다.
// 생성자 함수
function Base(a) {
this.a = a;
}
// 생성자 함수를 상속받는 서브클래스
class Derived extends Base {}
const derived = new Derived(1);
console.log(derived); // Derived {a: 1}
◎ super 키워드
다음과 같이 동작한다
- super를 호출하면 수퍼클래스의 constructor를 호출한다.
- super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다.
- super를 호출
super를 호출하면 수퍼클래스의 constructor를 호출한다.
// 수퍼클래스
class Base {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
// 서브클래스
class Derived extends Base {
// 다음과 같이 암묵적으로 constructor가 정의된다.
// constructor(...args) { super(...args); }
}
const derived = new Derived(1, 2);
console.log(derived); // Derived {a: 1, b: 2}
// 수퍼클래스
class Base {
constructor(a, b) { // ④
this.a = a;
this.b = b;
}
}
// 서브클래스
class Derived extends Base {
constructor(a, b, c) { // ②
super(a, b); // ③
this.c = c;
}
}
const derived = new Derived(1, 2, 3); // ①
console.log(derived); // Derived {a: 1, b: 2, c: 3}
1. 서브클래스에서 constructor를 생략하지 않은 경우 서브클래스의 constructor에서는 반드시 super를 호출해야 한다.
2. 서브클래스의 constructor에서 super를 호출하기 전까지 this를 참조할 수 없다.
3. super는 반드시 서브클래스의 constructor에서만 호출한다.
- super를 참조
메서드 내에서 super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다.
1. 서브클래스의 프로토타입 메서드 내에서 super.sayHi는 수퍼클래스의 프로토타입 메서드 sayHi를 가리킨다.
// 수퍼클래스
class Base {
constructor(name) {
this.name = name;
}
sayHi() {
return `Hi! ${this.name}`;
}
}
// 서브클래스
class Derived extends Base {
sayHi() {
// super.sayHi는 수퍼클래스의 프로토타입 메서드를 가리킨다.
return `${super.sayHi()}. how are you doing?`;
}
}
const derived = new Derived('Lee');
console.log(derived.sayHi()); // Hi! Lee. how are you doing?
2. 서브클래스의 정적 메서드 내에서 super.sayHi는 수퍼클래스의 정적 메서드 sayHi를 가리킨다.
// 수퍼클래스
class Base {
static sayHi() {
return 'Hi!';
}
}
// 서브클래스
class Derived extends Base {
static sayHi() {
// super.sayHi는 수퍼클래스의 정적 메서드를 가리킨다.
return `${super.sayHi()} how are you doing?`;
}
}
console.log(Derived.sayHi()); // Hi! how are you doing?
상속 클래스의 인스턴스 생성 과정은 460p를 상세히 읽어볼 것.
'Frontend > modern javascript' 카테고리의 다른 글
[Modern javascript] 배열(1) (0) | 2021.09.12 |
---|---|
[Modern javascript] ES6 함수의 추가 기능 (0) | 2021.09.02 |
[Modern javascript] 클래스(1) (0) | 2021.08.31 |
[Modern javascript] 클로저 (0) | 2021.08.31 |
[Modern javascript] 실행 컨텍스트(2) (0) | 2021.08.28 |