타입스크립트: 클래스

공대적 문과생·2022년 1월 20일
0

클래스

... 를 공부하려면 JS 클래스부터 다시 공부하고 와야할 것 같다. 제가 해석한 내용에 오류가 있으면 호되게 꾸짖어주세요.

자바스크립트의 클래스

클래스가 뭔지는 대충 알고.

클래스는 다음과 같이 선언한다.

class Rectangle {
	constructor(height, width) {
		this.height = height;
		this.width = width;
	}
}

여기서 constructor (생성자) 라는 것은 클래스의 인스턴스를 생성할 때, 클래스에 제공해줘야 하는 인수 같은 걸 설정한다. 이 인수를 기반으로 클래스는 속성(멤버 변수)의 초기값을 만든다.

생성자 함수 (constructor function)

클래스와 비슷하게, 자바스크립트에서 비슷한 객체를 만들기 위한 방법 중 하나다.

function Person(name) {
	this.name = name;
	this.introduce = function(){
		return 'My name is '+this.name;
	}
}

let p1 = new Person('egoing');
document.write(p1.introduce()+"<br />");

let p2 = new Person('m00n');
document.write(p2.introduce());
  1. 함수 이름의 첫 글자는 대문자로 시작한다. 일반 함수와 의미적으로 구분하기 위함이다.
  2. 반드시 new 연산자를 붙여 실행한다. 이 경우 내부에 this를 암시적으로 생성하며, 마지막엔 this가 반환됨.

생성자 함수는 클래스와 뭐가 다른건가? 애초에 클래스도 함수인건가..?.?

https://velog.io/@mnz/JavaScript-%EC%83%9D%EC%84%B1%EC%9E%90%EC%99%80-new%EB%9E%80 에 따르면, 생성자 함수를 일반 함수와 다르게 하는 것은, 호출 시에 new를 붙이는 점이다. new를 붙이면 위의 기술과 같이, this를 생성하고 반환한다.

https://ko.javascript.info/constructor-new에 따르면 new를 붙이지 않더라도, new를 붙여서 리턴하는 방법이 있다고 한다. 생성자 함수임을 알기 어려우므로, 권장하지는 않음.

function User(name) {
	if (!new.target) { return new User(name) }
	// 이런 것을 보고 재귀함수라고 하던가

	this.name = name;
}

let bora = User("보라");
alert(bora.name);

생성자 함수는 자동으로 this를 반환하기 때문에 return 문은 필요없지만, 별도로 return을 지정할 경우, this를 무시하고 return문이 적용된다고 한다.

https://uiyoji-journal.tistory.com/101
생성자 함수는 클래스와 비슷한 일을 할 수 있지만, 생성자 함수가 만든 객체는 인스턴스마다 메서드를 중복해서 만들고 메모리를 각자 차지하게 하는 문제가 있다. 이 경우 우리는 prototype을 고려해볼 수 있다. 프로토타입은 이 링크에 잘 설명돼있는 것 같으니 나중에 공부하자.

드디어 진짜 클래스

https://ko.javascript.info/class 에 따르면 클래스는 ES2015 (ES6)에서 도입된 문법이고, 이해한 바에 의하면 새롭게 등장한 개념이 아니라, 클래스는 생성자 함수와prototype을 좀 편리하게, 다른 객체지향 언어처럼 처리해주는 것 같다. 말하자면 promise를 readable하고 간편하게 만든 것이 async, await인 것과 같은 맥락인 모양. → 링크의 설명을 보면 조금 다르기는 하다고 하는데... 본질적으로 같다는 것만 알고 넘어가도록 하자.

웹이 어려운 이유는 좌충우돌의 웹 기술 역사를 공부해야 하는 점인것 같다. 😂 이제야 작년 재작년에 공부했던 리액트의 클래스형/함수형 컴포넌트 차이를 좀 알 것 같다. 너무 늦었지 ..

클래스 필드는 나중에 공부하자.

호이스팅 (Hoisting)

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

자바스크립트에서 함수/변수 등을 선언하고 사용할 때. 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것. 선언부를 상단으로 옮겨서 해석한다고 보면 된다는 듯

따라서 변수나 함수를 먼저 초기화/사용하고 후에 선언해도 문제가 없다. 그러나 자바스크립트는 초기화를 제외한 선언만 호이스팅하므로, 실질적으로 초기화가 있기 전에 변수를 사용하면 undefined가 뜬다.

https://velog.io/@cada/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%EC%9D%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85Hoisting

함수와 변수는 선언이 호이스팅되지만, 클래스는 그렇지 않다. 클래스는 반드시 선언 뒤에 사용해야 한다.

갑자기 궁금한 매개변수/인자(parameters)와 인수(arguments)의 차이

파라미터/매개변수(parameters)는 함수를 정의할 때 외부에서 받아들이는 임의의 값을 담는 변수, 인수(arguments)는 함수를 호출할 때 함수에 제공하는 값들.

https://zetawiki.com/wiki/%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98(parameter)%EC%99%80_%EC%9D%B8%EC%88%98(argument)%EC%9D%98_%EC%B0%A8%EC%9D%B4

#include <stdio.h>

int plus(int a, int b) // a, b 는 매개변수(parameter) {
    return a + b;
}

void main()
{
 int result = plus(1, 2); // 1, 2 는 인수(argument)    printf("%d", result);

왜 클래스 얘기하다가 여기까지 가는지 😂
확실히 자바스크립트에 대해 너무나도 몰랐다.


돌고 돌아 타입스크립트 핸드북으로 돌아와서 계속해보면 ..

readonly

타입스크립트에서는 클래스의 속성에 readonly 키워드를 사용해 접근만 가능하도록 만들 수 있다.

class Developer {
	readonly name: string;
	constructor(theName: string) {
		this.name = theName	
	}
}

let john = new Developer("John");
john.name = "John"; // error! name is readonly.

constructor() 함수에 초기값 설정 로직을 생략하기 위해 파라미터에 readonly를 사용할 수 있다.

class Developer {
	readonly name: string;
	constructor(readonly name: string) {
	}
}

접근자 (Accesor)

get, set 을 활용하는 방법

class Developer {
	private name: string;

	get name(): string {
		return this.name;
	}
	
	set name(newValue: string) {
		if (newValue && newValue.length > 5) {
			throw new Error('이름이 너무 깁니다');
		}

		this.name = newValue;
	}
}

const josh = new Developer();
josh.name = 'Josh Bolton'; // error. '이름이 너무 깁니다'
josh.name = 'Josh';

get만 선언하고 set을 선언하지 않으면 자동으로 readonly로 인식된다고 함.

추상 클래스 (Abstract Class)

타입스크립트에서 도입된 개념이며, 인터페이스와 비슷하지만 인터페이스가 타입에 주로 관여하는 반면, 추상 클래스는 직접적으로 클래스의 상속대상(부모)이 되며, abstract 키워드를 사용해 선언된 속성이나 함수는 상속을 받은 클래스에서 반드시 구현해야 되는 것 같다. 언제 어떻게 쓰는지는 감이 잘 안옴.

abstract class Developer {
  abstract coding(): void; // 'abstract'가 붙으면 상속 받은 클래스에서 무조건 구현해야 함
  drink(): void {
    console.log('drink sth');
  }
}

class FrontEndDeveloper extends Developer {
  coding(): void {
    // Developer 클래스를 상속 받은 클래스에서 무조건 정의해야 하는 메서드
    console.log('develop web');
  }
  design(): void {
    console.log('design web');
  }
}
const dev = new Developer(); // error: cannot create an instance of an abstract class
const josh = new FrontEndDeveloper();
josh.coding(); // develop web
josh.drink(); // drink sth
josh.design(); // design web
profile
공대적 문과생, 추남적 미남, 여성적 남성, 신사적 변태, 이론적 로맨티시스트, 현실적 이상주의자.

0개의 댓글