Class [feat. extends와 super]

이진혁·2022년 9월 23일
0
post-thumbnail

Class란?

class 문법은 constructor, prototype 을 이용한 상속기능을 만들어주는 문법이다.

function부터 시작하던 문법과 기능상 차이는 크게 없지만 class를 이용하면 더욱 직관적이고 보기 쉽게 만들 수 있다

아래의 코드를 살펴보자

class 부모 {
  constructor(){
    this.name = 'Kim'
  }
}

let 자식 = new 부모();

굉장히 간단하게 class를 이용한 상속기능을 만들어 보았다

function 부모(){} 어쩌구 저쩌구 이렇게 생성자 함수를 만드는 문법과 똑같은 문법이다

new 키워드를 이용해 부모라는 class 안에서 오브젝트를 생성할 수 있다.

constructor() 라고 쓴 부분에는 this.name this.age 등 적으면 새로 생성되는 오브젝트들에 값을 부여할 수 있다.

상속가능한 함수를 추가하려면?

상속가능한 함수를 만들기 위해서는 두 가지 방법이 있다

  1. 함수를 consturctor 안에 추가하는 방법
  2. 생성자 함수의 prototype 안에 추가하는 방법

함수를 consturctor 안에 추가하는 방법

class 부모 {
  constructor(){
    this.name = 'Kim';
    this.sayHi = function(){ console.log('hello') } //가능
  }
}

let 자식 = new 부모();

위의 코드를 살펴보면 constructor 안에 함수를 추가했다.

그럼 이제부터 새로 생성되는 자식은 sayHi() 함수를 직접 가지게 되며 자유롭게 사용할 수 있다

생성자 함수의 prototype 안에 추가하는 방법

class 부모 {
  constructor(){
    this.name = 'Kim';
  }
  sayHi(){ 
    console.log('hello') 
  }
}

let 자식 = new 부모();

이번에는 constructor 안에가 아니라 밖에서 sayHi()라는 함수를 추가해줬다

이렇게 되면 생성자 함수 prototype 안에 sayHi()라는 함수가 생겨나는데 class를 통해 생성되는 새로운 자식 객체들은 prototype 덕분에 sayHi()라는 함수를 사용할 수 있게 된다.

즉, 1번과 2번의 공통점은 새로 생성되는 자식 객체들이 sayHi()라는 함수를 사용할 수 있다는 것.

차이점은 1번을 통해 만들게 되면 자식 객체가 sayHi()를 직접 갖게 되고
2번을 통해 만들게 되면 부모의 prototype 안에 sayHi()가 있기 때문에 참조해서 사용할 수 있다는 것이다

**참고로 Object.getPrototypeOf(자식) 을 사용하면 부모 prototype을 출력해준다

proto라는 키워드와 비슷한 역할을 한다

constructor안에 파라미터 추가하기

ES6 방식으로 constructor 만들 때 파라미터를 추가하려면

class 부모 {
  constructor(이름, 나이){
    this.name = 이름;
    this.age = 나이;
  }
}

let 자식 = new 부모('Park', 30);

이런 식으로 하면 파라미터를 넣어서 constructor를 만들 수도 있다.

여기까지 class 문법을 이용한 상속기능을 만들어 보았다.

그렇다면 조금 더 나아가서 자바스크립트 객체지향 문법의 끝판왕인 extends에 대해서 알아보자

class를 상속한 class를 만들고 싶을 때 쓰는 extends

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

할아버지라는 class를 하나 만들어보았다.

할아버지 class는 성과 이름이라는 속성을 가지고 있는데 new 할아버지()를 통해 새로운 오브젝트를 생성할 수 있다

근데 만약 이 class가 너무 유용해서 이것과 유사한 class를 만들고 싶다면 어떻게 해야 할까?

그럴때 extends를 사용하면 매우 쉽게 만들 수 있다!

쉽게 말하면 extends는 다른 class를 상속해서 만들 수 있게 도와주는 문법이다

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지{

}

할아버지를 extends한 아버지라는 새로운 class를 만들었다

그럼 이제 할아버지라는 class를 그대로 복사한 아버지라는 class가 생성된다

아버지라는 class에는 새로운 속성을 추가하고 싶으면

당연히 아버지 constructor안에 내용을 추가하면 된다

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지{
  constructor(){
    this.나이 = 50;
  }
}

let 오브젝트 = new 아버지();
console.log(오브젝트)

한 번 출력해보자!

띠용 에러가 난다

해석해보면 constructor 안에 super를 써야 한다고 에러가 난다

그럼 넣어주면 된다

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지{
  constructor(){
    super();
    this.나이 = 50;
  }
}

let 오브젝트 = new 아버지();
console.log(오브젝트)

super()라는 함수는 extends로 상속중인 부모 class의 constructor()를 의미한다

쉽게 말하면 할아버지 class의 constructor() 이거랑 똑같다는 소리이다

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지{
  constructor(){
    super() == constructor(name){
                  this.= 'Kim';
                  this.이름 = name;
                 } 
    this.나이 = 50;
  }
}

let 오브젝트 = new 아버지();
console.log(오브젝트)

이렇게 super를 추가해줘야 에러가 나지 않고 아래와 같이 잘 출력이 된다

근데 할아버지 class의 constructor()에는 name 파라미터를 입력할 수 있었다

똑같이 상속을 받고 싶다면 할아버지가 가진 모든 속성들을 넣어줘야 정확히 상속 받을 수 있다

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
}

class 아버지 extends 할아버지{
  constructor(){
    super(name) 
    this.나이 = 50;
  }
}

let 오브젝트 = new 아버지();
console.log(오브젝트)

할아버지 constructor()에 name이라는 파라미터가 있던걸 그대로 아버지 constructor()에도 따라했다.

이제 그럼 new 아버지(); 할 때 파라미터를 입력하면 this.이름 속성에 들어가게 된다.

할아버지에 함수를 추가한다면?

할아버지 class 안에 함수를 추가한다면 아버지 class의 자식들도 물려받아 쓸 수 있을까?

class 할아버지{
  constructor(name){
    this.= 'Kim';
    this.이름 = name;
  }
  sayHi(){
    console.log('안녕 나는 할아버지')
  }
}

class 아버지 extends 할아버지{
  constructor(name){
    super(name);
    this.나이 = 50;
  }
}

let a = new 아버지('만수');

그럼 이제 a라는 오브젝트는 sayHi()라는 함수를 쓸 수 있다

왜일까?

a라는 오브젝트가 a.sayHi() 이렇게 사용한다면

  1. a라는 오브젝트에 sayHi가 있는지 물어보고
  2. 없으면 아버지.prototype에 sayHi가 있는지 물어보고
  3. 없으면 할아버지.prototype에 sayHi가 있는지 물어보고

이런 식으로 sayHi를 실행하기 위해 부모님을 뒤져본다.

근데 sayHi()라는건 할아버지.prototype에 추가된 함수이기 때문에

a라는 오브젝트는 sayHi() 함수를 실행할 수 있는 것이다.

느낀점

사실 그동안 class 문법을 여기저기서 찾아볼 수 있었는데 스스로 사용하기 조금 까다롭다고 여겼는지 그동안 눈길 조차 주지 않았다

그래서 매번 나중에 공부해야지 하며 미뤘었는데 더이상은 class의 애처로운 눈빛을 차마 외면하지 못 하고 열심히 정리하고 공부해봤다

prototype, constructor에 대해 어느정도 이해하고 있기 때문일까

생각보다,, 간단하네,,?

profile
개발 === 99%의 노력과 1%의 기도

0개의 댓글