본문 바로가기
Frontend/JavaScript

JavaScript의 class를 사용해보자

by 코딩쥐 2024. 7. 30.

클래스(Class)

원래 JavaScript에서는 생성자 함수라는 방식을 통해서 객체를 생성했었다. 생성자 함수의 경우 유지보수나 상속에 어려움이 있었다. 이러한 점을 개선하기 위해 ECMA2015부터 class 개념이 등장한다. class의 경우에는 함수선언식과 다르게 호이스팅이 되지 않아 클래스를 반드시 정의한 후에 사용할 수 있다. 

  • class 클래스이름 {
       멤버변수;
       메서드명(){};
    }

  • let | const 인스턴스이름 = new 클래스이름();

 

Property

class내에서는 property(객체가 지닌 속성 / 변수 등)를 설정하는 것이 가능하다.  class내에 직접 선언하거나, 메서드 내에서 this를 통해 property를 바인딩하는 방법이 있다. class내에서는 글로벌 함수로의 this 접근이 적용되지 않기 때문에, class내에서 에러가 나지 않게 하기 위해서는 값을 받은 인스턴스에 따로 해당 이름의 프로퍼티를 선언해주어야만 한다.

 

 

Method

class에서 메서드 작성시에는 function과 :이 들어가지 않고 메서드 명만 작성한다. class에 선언된 메서드들은 전부 prototype에 저장된다.

  • static 메서드 : 객체에서는 사용되지 않고 클래스 자체에서 호출되는 메서드이다. static 메서드의 경우에는 this.constructor를 통해 접근이 가능하다. 

Constructor

class 인스턴스를 생성하고 생성한 인스턴스를 초기화 하는 역할을 한다. 이전에 생성자 함수 설명할 때 얘기했던 prototype 프로퍼티 안에 들어있는 constructor와 비슷한 역할을 한다. 클래스에서 constructor를 생성하지 않으면 프로토타입에 존재하는 constructor가 실행된다. 

 

<<class 생성>>

        class Class1 {
            constructor(name, text) {
                this.name = name;
                this.text = text;
            }
            
            a = 10;

            callText() {
                console.log(`${this.name}은/는 ${this.text}`);
            }

            static callName() {
                return "안녕하세요.";
            }
        }
        let obj1 = new Class1("KTX는", "빠르다");
        console.log(obj1.constructor.callName()); // 안녕하세요.
        console.dir(obj1);
        obj1.callText(); // KTX는은/는 빠르다
        console.log(obj1.callName()); // TypeError: obj1.callName is not a function

 

새로 객체를 만들어서 확인해보면 멤버변수가 들어가 있는 것을 볼 수 있다. 메서드의 경우에는 [[prototype]]에 저장된 것을 볼 수 있다. class 방식에서도 추가적인 속성 혹은 기능을 삽입하고 싶을 때는 기존에 있었던 생성자의 삽입 방식을 사용해서 삽입할 수 있다.  또한 static메서드의 경우에는 constructor에 접근해서 사용해야 사용이 가능한 것을 볼 수 있다. 

 

<<추가 메서드 삽입>>

        class Class1 {
            constructor(name) {
                this.name = name;
            }

            callText() {
                console.log(`${this.name}님`);
            }
        }
        
        //클래스의 프로토타입 프로퍼티에 메서드 삽입
        Class1.prototype.sayHello = function(){
            console.log(`${this.name}님 반갑습니다.`);
        }
        let obj1 = new Class1("코딩쥐");
        obj1.sayHello(); // 코딩쥐님 반갑습니다.

 

클래스 상속

  • class 자식클래스 extends 부모클래스 {}

자식클래스와 부모클래스 사이의 공통적인 생성자가 있을 경우 중복을 피하기 위해서 super()을 사용하여 부모클래스를 참조한다(부모클래스의 constructor는 상속되지 않고 참조되어야한다.).  자식클래스에서 constructor를 생략하는 경우에는 constructor{super();}가 기본값으로 들어가기 때문에 작성하지 않아도 된다. 

 

<<클래스 상속>>

        // 부모 class 설정 : TV
        class TV{
            constructor(display){
                this.display = display;
            }

            turnOn(){
                console.log(`${this.display}TV를 켭니다.`);
            }
            turnOff(){
                console.log(`${this.display}TV를 끕니다.`);
            }
        }

        // 자식 class 설정 : ottTV
        class OttTV extends TV{
            constructor(display, ott){
                // 부모 class의 display를 상속받는다. 
                super(display);
                this.ott = ott;
            }

            turnOtt(){
                console.log(`${this.ott}를 켭니다.`);
            }
        }

        // OttTV의 새로운 객체를 생성하고 나면, 부모클래스의 TV를 상속받았기 때문에 TV의 기능과 속성도 사용할 수 있다.
        let obj1 = new OttTV("24인치", "유튜브");
        obj1.turnOn(); // 24인치TV를 켭니다.
        obj1.turnOtt(); // 유튜브를 켭니다.
        obj1.turnOff(); //24인치TV를 끕니다.


오버라이딩

부모 클래스로 상속받은 기능을 자식이 동일하게 선언하여 자신의 기능으로 덮어씌울 수 있다. 그리고 부모의 기능에 강제로 접근하는 방법은 super을 사용하면 된다. 

 

<<오버라이딩>>

        // 부모 class 설정 : TV
        class TV{
            constructor(display){
                this.display = display;
            }

            turnOn(){
                console.log(`${this.display}TV를 켭니다.`);
            }
            turnOff(){
                console.log(`${this.display}TV를 끕니다.`);
            }
        }

        // 자식 class 설정 : ottTV
        class OttTV extends TV{
            constructor(display, ott){
                // 부모 class의 display를 상속받는다. 
                super(display);
                this.ott = ott;
            }

            //부모 class의 turnOn()을 오버라이딩
            turnOn(){
                console.log(`${this.display} ottTV를 켭니다.`)
            }

            turnOtt(){
                console.log(`${this.ott}를 켭니다.`);
            }

            //부모 class의 turnOff()를 오버라이딩
            turnOff(){
                console.log(`${this.display} ottTV를 끕니다.`)
            }

            //부모 class의 turnOn() 불러오기 
            turnOnParent(){
                super.turnOn();
            }
        }

        // OttTV의 새로운 객체를 생성하고 나면, 부모클래스의 TV를 상속받았기 때문에 TV의 기능과 속성도 사용할 수 있다.
        let obj1 = new OttTV("24인치", "유튜브");
        obj1.turnOn(); // 24인치 ottTV를 켭니다.
        obj1.turnOtt(); // 유튜브를 켭니다.
        obj1.turnOff(); // 24인치 ottTV를 끕니다.
        obj1.turnOnParent(); // 24인치TV를 켭니다.