https://ko.javascript.info/class-inheritance
클래스 상속
class Parent {
field = 'a'
say(){
console.log('im your father')
}
}
class Child extends Parent{
}
상속받은 클래스 Child는 부모의 메서드와 필드를 다 사용할 수 있다
const ch = new Child()
console.log(ch.field) // im your father
ch.say() // a
메서드 오버라이딩
위에서 처럼 say 함수를 그대로 사용할 수도 있지만 자체적으로 다른 함수를 사용하고 싶다면 그냥 동일 명의 함수를 필드에 작성하면된다
class Child extends Parent{
say() {
console.log('im your son')
}
}
이전의 메서드 console.log('im your father')
는 console.log('im your son')
에 의해 지워진다
super
그대로 사용하고 일부분만 변경하고 싶거나 자체적으로 메서드를 사용하고 상속받은 메서드도 사용하고 싶을 때 super를 사용한다
class Child extends Parent{
say() {
super.say()
console.log('im your son')
}
}
const ch = new Child()
console.log(ch.field) // a
ch.say() // im your father \n im your son
생성자 오버라이딩
우선 생성자 오버라이딩을 알아보기 전에
자바스크립트에서 일반적인 클래스와 상속을 받은 클래스는 내부 프로퍼티가 다르다 이 다름은 클래스로 인스턴스를 생성할 때 차이가 나는데
일반 클래스로 객체를 생성할 경우 빈 객체가 만들어진 뒤 this가 생성되고 다시 this가 이 객체를 할당한다
상속받은 클래스로 객체를 생성할 경우에 빈 객체가 만들어지고 this가 생성되어야하는데 이 단계의 일을 부모한테 넘겨버린다
이 때 상속받는 클래스는 생성자를 생략해도 된다 자식이 생성해야 할 일을 부모가 대신 생성해주는셈
class Parent {
constructor(name) {
this.lastname = name
this.firstname = 'Jhon'
}
say(){
console.log('im your father')
}
}
class Child extends Parent{
/*
이 쯤에 constructor가 생략되어있고 생략되어있다면 부모의 constructor가 대신 실행된다
실제로 내부적으로 실행되는 코드는 아래와 같다
constructor(...args) {
super(...args);
}
*/
say() {
console.log(`my name is ${this.firstname}`)
}
}
const ch = new Child('James')
ch.say() // my name is Jhon
그렇기 때문에 Child내부에 생성자가 없음에도 Parent클래스에 존재하는 생성자가 실행돼어 firstname값이 존재하는 것
생략되어있을 때는 위와 같이 작동하는데.. 자식에게 스스로 생성자가 있다면?
어림도 없지 에러!
자식에게 생성자가 명시되어있다고 해도 this를 스스로 생성할 수 없기 때문에 부모가 무조건 도와주어야한다
자식에게 this를 생성해주는 코드가 바로 위에서 생략되어있는 super()인 셈
class Parent {
constructor(name) {
this.lastname = name
this.firstname = 'Jhon'
}
say(){
console.log('im your father')
}
}
class Child extends Parent{
constructor(name) {
super()
this.lastname = name
}
say() {
console.log(`my name is ${this.firstname} ${this.lastname}`)
}
}
const ch = new Child('James')
ch.say() // my name is Jhon James
클래스 필드 오버라이딩
class Parent {
nickname = 'giant'
constructor() {
console.log(this.nickname)
}
}
class Child extends Parent{
nickname = 'little boy'
}
new Parent() // giant
new Child() // giant
생성자 함수에 클래스 필드로 정의된 닉네임을 로그로 출력하게끔 만든 클래스를 불러왔다
Parent는 자신의 클래스 필드에 있는 giant를 부르고 있는데 왜 Child는 자신의 클래스 필드에 있는 little boy를 불러오지 않은 걸까?
답은 역시 자바스크립트의 제멋대로 생성자에 있는데 이를 알아보기전에 두 가지를 먼저 기억해주어야한다
일반 클래스는 생성자가 호출되기 전에 클래스 필드를 먼저 초기화한다는 점을 상기하고
클래스 필드는 선언한 이후 this.필드이름 으로 접근할 수 있다는 점을 상기하자
위에서 배운 내용을 바탕으로 Child로 객체를 생성할 때 어떤 과정을 거치는지 다시 생각해보자
클래스 필드 닉네임이 있다 이 닉네임은 클래스로 객체를 생성할 때 빈 객체를 만들어서 this를 할당시키고 this.nickname으로 초기화 해주어야한다
그런데 여기서 자식 클래스인 Child는 스스로 this를 만들지 못한다
그렇기 때문에 클래스 필드를 초기화 하기 전에 this를 만들기 위해 부모의 constructor을 먼저 실행한 후에 nickname이 this에 초기화된다
먼저 부모의 constructor을 실행하는 과정에서 Child의 클래스필드는 존재하지 않고 그렇기 때문에 부모의 클래스 필드인 giant가 로그에 찍히게 되는 것
get set
'JavaScript' 카테고리의 다른 글
parentElement vs parentNode (0) | 2021.05.25 |
---|---|
Element.closest() (0) | 2021.05.24 |
local/session Storage (0) | 2021.05.22 |
fetch API (0) | 2021.05.21 |
바닐라 자바스크립트로 컴포넌트 만들기 -2 (0) | 2021.05.19 |