[레벨1-자판기] 기억 남는 프로로그

⌛ 레벨1의 마지막 미션이네요.

이번 미션에서는 json-server를 사용하여 회원가입과 로그인을 구현했어요.

그 과정에서 다양한 고민들이 있었는데 프로로그를 살펴보니 크루들도 비슷한 고민을 하신 흔적들이 보이더라구요!

그럼 살펴볼까요?


💪 객체의 속성 값을 삭제해야할 때

방법 1) ✨delete를 사용합니다.

성공 시: true
실패 시: 비엄격모드 false / 엄격모드 TypeError, SyntaxError

  • delete는 자기 자신의 속성에만 효과가 있어요.

  • 하지만.. 삭제할 속성이 없는 경우에도 true를 반환할 것을 고려해야 하고 예상치 못한 false가 반환될 것에 대비해서 예외 처리를 추가해야 한다. delete가 깔끔하진 않네요.

방법 2) ✨구조분해할당+나머지연산자 조합으로 해결할 수 있어요.

const obj = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

// 'first'와 'third' 삭제하기
const { first, third, ...exceptBoth } = obj

console.log(exceptBoth)     // { 'second': 'two' }

💪 콜백함수

콜백함수는 다른 코드(함수 또는 메서드)에게 인자를 넘겨줌으로써 그 제어권🎮도 함께 위임한 함수입니다.

this

  • 함수 선언문으로 선언한 콜백 함수도 함수이기 때문에 기본적으로는 this가 전역객체를 참조합니다.

  • 하지만 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조하게 됩니다.

this 지정하기

  • 지정하는 방법은 명시적 바인딩 call/apply/bind이 있습니다.

(❗예외적으로 addEventListener는 event target이 this에 바인딩 됩니다.)

  • 화살표 함수의 경우에는 바인딩되지 않고 상위 스코프의 this를 가리킵니다.

💪 테스트 코드 작성 이유

요구사항 기반으로 발생할 수 있는 모든 예외케이스에 대해섯 작성을 합시다. (짤꺼면 제대로!!)

  1. 리팩토링 오류 과정에서 오류와 직접적으로 연관된 부분을 테스트 코드를 통해 확인할 수 있어요.

  2. 테스트 코드만으로 해당 프로덕트 기능에 대한 이해도를 높일 수 있어요.

  • 오랜 시간이 지나면 개발자 또한 기능에 대한 이해도가 떨어지게 됩니다.
  • 이 경우 잘 짜여진 테스트 코드를 보게 된다면, 쉽게 기능에 대한 예외사항을 파악할 수 있습니다.

💪 MIME(Multipurpose Internet Mail Extensions)

🤔🤔 자판기 미션에서 로그인할 때 API에 headers: { 'Content-type': 'application/json' }를 주지 않으면 동작을 제대로 안했죠. 왜 그럴까요?

❗ 웹에서는 파일의 확장자가 의미가 없어요.

  • 브라우저는 리소스를 내려받고 MIME 타입을 봐야지만 다음으로 해야할 동작을 결정할 수 있거든요!

즉, MIME은 다양한 형태의 파일을 전달할 때 파일 변환을 알려주기 위한 일종의 포맷이라고 할 수 있겠습니다.


💪 CORS (Cross Origin Resource Sharing) 에러

도메인이 다른 서버끼리 서로 리소스를 주고 받는 것

🛡️ 기본적으로 웹 브라우저는 Same Origin

  • origin이 같다는 것은 URL스킴(프로토콜), 도메인, 포트가 모두 같다는 말입니다.
  • 다른 도메인으로부터 보호하는 일종의 보안 정책인 것이죠.

🎯 CORS

  • 하지만 다른 도메인 사이에서도 주고 받을 필요가 있겠죠.
  • 이 때 CORS를 이용하면 됩니다.
  • CORS는 서버에서 리소스 접근이 허용된 origin(클라이언트)에 대한 정보를, HTTP 헤더로 추가하여 동작합니다.

💪 상수를 타입스크립트로

readonly

type Foo {
	readonly bar: number;
	readonly bas: number; 
}

let foo:Foo = { bar:'bar', bas,:'bas' }; // ok

foo.bar = 'bas'; // Error

readonly 타입으로 지정된 객체 속성은, 초기화는 가능하지만 변경이 불가능 합니다. (읽기전용)

as const

const foo = 'bar' as const;

foo는 그저 'bar'일뿐, string타입으로 확장도지 않습니다!


💪 생성자 파라미터에서 초기화

기존 코드

class App {
  private productDomain;
  private coinDomain;
  private productManagementUI;
  private coinManagementUI;
  private productPurchaseUI;

  constructor() {
    this.productDomain = new ProductManagementDomain();
    this.coinDomain = new CoinManagementDomain();
    this.productManagementUI = new ProductManagementUI(this.productDomain);
    this.coinManagementUI = new CoinManagementUI(this.coinDomain);
    this.productPurchaseUI = new ProductPurchaseUI();
  }
}

바뀐 코드

class App {
  constructor(
    private readonly productDomain = new ProductManagementDomain(),
    private readonly coinDomain = new CoinManagementDomain(),
    private readonly productManagementUI = new ProductManagementUI(productDomain),
    private readonly coinManagementUI = new CoinManagementUI(coinDomain),
    private readonly productPurchaseUI = new ProductPurchaseUI()
  ) {}
}

👆 각 멤버변수에 모두 타입을 준다면 constructor에서 선언과 동시에 초기화를 할 수 있어요.

❓ 그런데 this를 안 써도 괜찮나요?
네! 그렇습니다.

생성자의 파라미터로 접근 제한자가 사용된 경우, 암묵적으로 클래스 프로퍼티로 선언되고 생성자 내부에서 별도의 초기화 과정 없이도 암묵적인 초기화가 수행됩니다.


💪 더 나은 페어 프로그래밍

페어 프로그래밍 템플릿

좋은 웹페이지 즐겨찾기