자식 클래스가 생성자를 오버라이딩 하는 경우
자식 클래스의 생성자가 호출됐을 때 무조건 부모 클래스의 생성자도 호출된다. 그런데, 자식클래스가 생성자를 오버라이딩 하는 경우가 생긴다.
class Car {
constructor (name, type, price) {
this._name = name;
// ...생략
}
}
class ElectronicCar {
constructor (name, price, chargeTime) {
super(name, 'e', price);
this._chargeTime = chargeTime;
}
set chargeTime(value) {
this._chargeTime = value;
}
}
const elecCar = new ElectronicCar("차 이름", 9000);
예를들어 이와같이 Car를 상속받은 ElectronicCar는 타입을 굳이 생성자에 넣어줄 필요는 없다. 하지만 자동으로 부모 클래스의 상속자가 호출될 때는 타입의 정보가 필요하기 때문에 이 값들로 초기화하면 된다고 값을 보내줘야 한다!
부모클래스의 생성자를 호출한 뒤 부모 클래스에선 필요하지 않던 값을 이 객체의 값으로 초기화 시켜준다.
만약 getter, setter를 사용하는 경우 this._(변수명)을 통해 접근하는 것을 잊지말자~
클로저 (Closure)
클로저란?
함수와 그 함수가 선언된 렉시컬 환경과의 조합
외부함수보다 중첩함수가 더 오래 유지되는 경우, 중첩합수는 생명주기가 끝난 외부함수의 변수를 여전히 참조할 수 있다.
이때의 중첩함수를 클로저라고 한다!
렉시컬 환경
const x = 1;
function outerFunc() {
const x = 10;
innerFunc();
function innerFunc() {
console.log(x);
}
}
outerFunc();
위의 경우 innerFunc()의 x는 어떤 값을 참조하는걸까?
innerFunc()의 스코프에 x가 없기때문에 outer인 outerFunc의 x = 10을 참조한다.
호출된 당시의 환경 X, 함수가 선언된 당시의 환경 (=== 렉시컬 환경)!
const x = 1;
function outerFunc() {
const x = 10;
innerFunc();
}
function innerFunc() {
console.log(x);
}
outerFunc();
위의 경우 1이 출력된다. 마찬가지로 innerFunc를 호출한 위치와 상관없이 선언했을 때의 외부환경을 참조하고 있기 때문!!
const x = 1;
function outer() {
const x = 10;
const inner = function() {
console.log(x);
};
return inner;
}
const innerFunc = outer();
// inner를 반환하고 outer의 실행컨텍스트 종료!
innerFunc();
마지막 부분에서 innerFunc()를 호출했을 때 inner가 참조하고있는 선언 당시 outer 환경은 이미 소멸되고 없다.
하지만 innerFunc() 를 호출하면 출력되는 x는 outer의 10이다!
이게 클로저 개념이다.
가비지컬렉터
이게 가능한 이유는 가비지컬렉터가 가비지를 정리할 때 아직 사용중인 값은 정리하지 않기 때문이다.
outer의 x를 사용하는 inner가 아직 소멸되지 않고 남아있으므로 정리되지 않고 남아있다!
클로저의 활용
클로저는 주로 상태를 안전하게 변경하고 유지하기 위해 사용한다!
예시
let num = 0;
const increase = function() {
return num++;
};
console.log(increase()); // 1
num = 100;
console.log(increase()); // 101
console.log(increase()); // 102
보완해야할 사항
- num 값은 increase 호출 전까지 변동되면 안된다.
const increase = (function () => {
let num = 0;
return function() {
return num++;
};
})();
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3
위 코드의 실행 단계
1) increase()를 선언하며 즉시실행함수 호출
- 함수가 반환되어 increase에 할당됨
- 즉시실행함수는 소멸됨!
2) increase에 할당됨 함수는 자신이 선언된 당시의 렉시컬 환경을 기억하는 클로저 (num = 0)
3) num은 무조건 increase를 통해서만 접근할 수 있기 때문에 은닉된 정보를 관리할 수있음
'JavaScript' 카테고리의 다른 글
[JS] 자바스크립트 실행 컨텍스트 (0) | 2024.08.02 |
---|---|
[JS] Scope, Class, this 바인딩 (0) | 2024.07.31 |
[JS] 참조타입의 변형을 막는 방법 (freeze, seal) (0) | 2024.07.25 |
[JS] 배열이 조건을 만족하는지 확인하기 (every, some) (0) | 2024.07.25 |
[JS] Generator 로그 순서 이해하기 (0) | 2024.07.24 |