수학과의 좌충우돌 프로그래밍

[ES6] Class의 상속, super, this 본문

웹프로그래밍/ES6

[ES6] Class의 상속, super, this

ssung.k 2020. 1. 4. 19:00

Class

class 의 기본적인 형태를 알아봅시다.

class 의 개념적인 부분은 생략하고 javacript 에서 어떻게 사용되는지 위주로 다루도록 하겠습니다.

생성자는 constructor 를 통해 구현가능하고 instance 를 생성할 때는 new 를 사용하여 정의합니다.

class User {
  constructor(username, password){
    this.username = username; 
    this.password = password;  
  }
  introduce(){
    console.log(`My name is ${this.username}`);
  }
}

user = new User("minsung","1234");

user.introduce();
// My name is minsung

 

상속

기존에 존재하던 class 를 상속받기 위해서는 extends 를 사용합니다.

class User {
  constructor(username, password){
    this.username = username; 
    this.password = password;  
  }
  introduce(){
    console.log(`My name is ${this.username}`);
  }
}

class Admin extends User {
  adminIntro(){
    console.log(`I am ${this.username}(admin)`);
  }
}

admin = new Admin("root", "root");
admin.adminIntro();
// I am root(admin)

 

super

prameter 를 object 로 받기 위해서 destructure 를 사용해 코드를 약간 수정하였습니다.

super 는 상속받은, 원시 클래스를 호출해줍니다.

Admin 에서 constructor 를 추가하기 위해서는 원시 클래스 Usercontructor 를 먼저 불러와야 합니다.

class Admin extends User {
  constructor({username, password, email}){
    super({username, password});
    this.email = email;

  }
  adminIntro(){
    console.log(`I am ${this.username}(admin)`);
  }
}

admin = new Admin({
  username: "root",
  password: "root",
  email: "root@gmail.com"
});
admin.adminIntro();
// I am root(admin)

 

this

this 는 상당히 까다롭습니다.

상황에 따라 호출하는 것도 다르지만 이번 포스팅에서는 class 내에서의 this 에 대해서 알아보도록 하겠습니다.

class 안에서, 정확히는 생성자 안에서 사용되는this 는 새로 생긴 객체 묶입니다.

그렇기 때문에 user 를 만들었을 경우 생성자안에 this 는 아래와 같은 의미를 같습니다.

constructor(username, password){
  this.username = username; 
  this.password = password;  
}

constructor(username, password){
  user.username = username;
  user.password = password;
}

 

하지만 다음의 예제를 보면 this 가 다른 객체를 가르킵니다.

11, 18, 22 에서 출력하는 this 가 전부 다른 객체를 가르키게 되죠.

특정 객체에 EventListener 를 만들면 그 이벤트 핸들러 안에서의 this 는 해당 객체, 이벤트 타켓을 가르키게 됩니다. 따라서 다른 결과가 나오게 되는거죠.

class Counter {
  constructor({initialNumber = 0, counterId, plusId, minusId}){
    this.count = initialNumber;
    this.counter = document.getElementById(counterId);
    this.plusBtn = document.getElementById(plusId);
    this.minusBtn = document.getElementById(minusId);
    this.addEventListeners();
  }

  addEventListeners(){
    console.log(this);
    // Counter {count: 0, counter: span#count, plusBtn: button#add, minusBtn: button#minus}
    this.plusBtn.addEventListener("click", this.increase);
    this.minusBtn.addEventListener("click", this.decrease);
  }

  increase(){
    console.log(this);
    // <button id="add">+</button>
  }
  decrease(){
    console.log(this);
    // <button id="minus">-</button>
  }
}

new Counter({counterId: "count", plusId: "add", minusId: "minus"});


 

이러한 현상을 방지하기 위해서, 즉 thisclass 내부에서는 class 를 가르키게 할 수 있습니다.

바로 arrow function 을 사용하는 것입니다.

이 경우 모든 thisclassCounter 를 가르키게 됩니다.

addEventListeners(){
  console.log(this);
  // Counter {count: 0, counter: span#count, plusBtn: button#add, minusBtn: button#minus}
  this.plusBtn.addEventListener("click", this.increase);
  this.minusBtn.addEventListener("click", this.decrease);
}

increase = () => {
  console.log(this);
  // Counter {count: 0, counter: span#count, plusBtn: button#add, minusBtn: button#minus}
}
decrease = () => {
  console.log(this);
	// Counter {count: 0, counter: span#count, plusBtn: button#add, minusBtn: button#minus}
}

 

최종적인 코드는 다음과 같습니다.

class Counter {
  constructor({initialNumber = 0, counterId, plusId, minusId}){
    this.count = initialNumber;
    this.counter = document.getElementById(counterId);
    this.counter.innerText = initialNumber;
    this.plusBtn = document.getElementById(plusId);
    this.minusBtn = document.getElementById(minusId);
    this.addEventListeners();
  }

  addEventListeners = () => {
    this.plusBtn.addEventListener("click", this.increase);
    this.minusBtn.addEventListener("click", this.decrease);
  }

  increase = () => {
    this.count = this.count + 1;
    this.repaintCount();
  }
  decrease = () => {
    this.count = this.count - 1;
    this.repaintCount();
  }
  repaintCount = () => {
    this.counter.innerText = this.count;
  }
}

new Counter({counterId: "count", plusId: "add", minusId: "minus"});


html 파일입니다.

<body>
    <span id="count">0</span>
    <button id="add">+</button>
    <button id="minus">-</button>
</body>

 

'웹프로그래밍 > ES6' 카테고리의 다른 글

[ES6] generator  (0) 2020.01.05
[ES6] proxy  (0) 2020.01.05
[ES6] Async and Await  (0) 2020.01.03
[ES6] Promises - then, catch, all, race, finally  (1) 2020.01.03
[ES6] Loop 에 대해서 알아보자 forEach, for of  (0) 2020.01.02
Comments