TypeScript Class

강정우·2023년 6월 13일
0

TypeScript

목록 보기
15/22
post-thumbnail

Class

  • class는 항상 대문자

constructor 함수

  • constructor 생성자 함수 => 다른 언어, JAVA, Dart같은 경우에는 생성자 함수가 클래스 이름인 경우가 대부분인데 TS에서는 constructor라고 따로 함수가 존재한다. 이는 최신 문법 ES6 이상에만 있는 함수이다.
class Department {
    name:string;
    constructor(n: string) {
        this.name = n;
    }
}

const CMS = new Department('SoftWare');
  • 만약 당신이 es5 이하로 JS 버전을 내렸다면 컴파일결과 코드가 조금 달라진 것을 확인할 수 있을 것이다.
var Department = (function () {
    function Department(n) {
        this.name = n;
    }
    return Department;
}());
var CMS = new Department('SoftWare');

"this" 키워드 문제

class Department {
    name:string;
    constructor(n: string) {
        this.name = n;
    }

    describe() {
        console.log('Department : ' + this.name);
    }
}

const CMS = new Department('SoftWare');

CMS.describe();

const CMScopy = {describe: CMS.describe}

CMScopy.describe();
  • log에 찍히는 2개의 값을 유츄해 보세요

정답

  • 왜일까? => 자세히 보면 CMScopy에 describe는 CMS.describe를 실행하는 것이 아닌 pointing하고 있다.
    그래서 CMS.describe 메서드에 적혀있는 this 가 더이상 원본 객체인 CMS를 pointing하고 있지 않다. 여기서 pointing하는 것은 CMScopy가 된다는 것이다.

  • 그렇다면 이러한 헷갈림을 방지하고싶다면 어떻게 하면 될까?
    => class에 this 값이 들어가는 메서드가 있다면 this 값의 type을 지정해주면 된다.

  • 이렇게 해주면 밑에서 CMScopy에서 describe를 메서드를 실행할 때 더이상 this가 Department의 인스턴스를 가르키는 것이 아니기 때문에 에러가 발생한다.
class Department {
    name:string;
    constructor(n: string) {
        this.name = n;
    }
    describe(this:Department) {
        console.log('Department : ' + this.name);
    }
}
const CMS = new Department('SoftWare');
const CMScopy = { name:'헬창 개발자', describe: CMS.describe}
CMS.describe();
CMScopy.describe();
  • 그리고 모든 속성값을 잘 넣어주면 객체가 완벽히 복사가 된다.

private, public

  • JAVA에서는 주구장창 썼던 기억이 새록새록 떠오른다. 그리고 front-end 프레임웤중에 state를 관리해주는 라이브러리도 역시 state(field값)에는 직접 접근하지 않도록 작성한다. 이처럼 TS또한 private와 public이라는 개념이 존재하나 JS에는 존재하지 않는다.

  • 그리고 위 코드를 컴파일 하면 아래와 같은 .js 파일을 얻는데 역시 private과 public을 나누는 코드는 볼 수 없다.
class Department {
    constructor(n) {
        this.employees = [];
        this.name = n;
    }
    describe() {
        console.log('Department : ' + this.name);
    }
    addEmp(emp) {
        this.employees.push(emp);
    }
    printEmpInfo() {
        console.log(this.employees.length);
        console.log(this.employees);
    }
}
const cms = new Department('SoftWare');
  • 더욱 자세한 정보는 Mozilla에서 확인하면 된다.

  • 따라서 TS는 런타임이 아닌 컴파일 과정에서 이를 검토하고 확인한다.

modifier + constructor

  • 그렇다면 모든 field값에 대해서 일일이 constructor 함수에 명시를 해줘야할까? =>
class Department {
    constructor(private id:string, private name:string) {}

    describe(this: Department) {
        console.log(`Department ${this.id}: ${this.name}`);
    }
}

const cms = new Department('d1', 'SoftWare');

cms.describe();
  • 이렇게 constructor 함수에 modifier를 함께 집어넣어 지정해주면 생성자 함수를 생성한 동시에 속성값을 선언해줄 수 있따.

readonly

  • 이 개념또한 TS에서 도입된 개념으로 이 키워드가 붙어있다면 인스턴스화를 할 때 1번 만 값이 설정된다.
class Department {
    constructor(private readonly id:string, private name:string) {}
  ...

ProtoTypes

https://developer.mozilla.org/ko/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

inheritance

class Department {
    constructor(private readonly id:string, private name:string) {}

    describe(this: Department) {
        console.log(`Department ${this.id}: ${this.name}`);
    }
}

class ITDepartment extends Department{
    constructor(id:string, public admins:string[]) {
        super(id, 'IT');
    }
}

const cms = new ITDepartment('d1', ['정우']);

cms.describe();
  • JAVA와 동일하게 오직 단 1개의 class를 상속받을 수 있다. 이때 생성자 함수 내부에는 항상 super 메서드부터 와서 상속에 필요한 모든 값들을 채워넣어줘야한다.

Protected

  • JAVA와 같이 private과는 다르게 extend하는 클래스 내부에서 해당 속성값에 접근할 수 있다.

getter

  • 이제 getter와 setter로 캡슐화를 해보겠다.

  • getter 메서드는 this.해당field 값을 반환해줘야한다.

setter

  • setter를 설정할 때 getter와 같은 네이밍으로 선언가능하다 다만, 반드시 매개변수가 있어야한다.

  • 이떄 getter, setter 모두다 메서드이지만 메서드로 접근하지 않고 모두 속성값처럼 접근해야한다.

abstract

  • JAVA와 같은 개념으로 class에 interface화라고 생각하면 된다. => 스스로 인스턴스화할 수 없다.
abstract class Class이름{
  constructor(private 속성1:타입, private readonly 속성2:타입, ...){}
  
  abstract 메서드1(this:Class이름): 반환타입;
}
  • 물론 field값도 abstract로 선언가능하긴하나 이는 abstract 클래스에서 필요한지, 만약 필요없다면 인스턴스화하는 클래스에서 이를 implement해줘야한다.

Static Class

  • 정적인 클래스 즉, 개발자가 동적으로 만들지 않고 미리 만들어진 클래스를 뜻한다 대표적으로 Math 클래스가 있다.

  • 그리고 만약 우리가 만든 커스텀 class에서 static하게 속성이나 메서드를 만든다면 이는 인스턴스화를 하지 않고도 사용할 수 있다.

  • 그리고 당연히 인스턴스화를 한 후 사용되는 this 키워드가 들어가있는 생성자 함수에는 static 속성값은 들어갈 수 없다.

singletone pattern의 private constructor

  • 이는 인스턴스화를 오직 한 번 할 수 있는 방법이다.

  • 이는 static을 사용할 수 없거나 사용하고 싶지 않을 때 사용하는 방식이다.

  • 이렇게 하면 new 키워드를 사용할 수 없게 된다. => 어떻게 인스턴스화를 할까? => static 메서드이다.

  • 이렇게 하면 정확히 똑같은 2개의 인스턴스가 생성된다.
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글