[JS_memo] 빌더패턴 & this바인딩 & 문자열 얼음시키기

Lina Hongbi Ko·2023년 2월 2일
0

JavaScript_memo

목록 보기
2/7
post-thumbnail

자바스크립트로 프로젝트하면서 느끼고 기록한것 - 2편


1. 프로젝트 하면서 빌더패턴 이용하기

드림코딩아카데미의 당근게임만들기를 하면서 최종적으로 refactoring할때 배운 것인데, 클래스들로 각 기능들을 묶고 c++처럼 private 기능을 주고 싶거나 오브젝트 생성시 필수로 필요한 인자들과 옵셔널적으로 설정할 수 있는 인자들을 명확하게 구별할 때 쓰면 좋다. 하나의 함수에 이름 없는 수많은 인자들을 전달해야하는 기존의 방식을 개선해 가독성을 높이는 것이 장점이다.

<script type="txt/javascript">

export class GameBuilder {
	withGameDuration(duration) {
    this.gameDuration = duration;
    return this;
    }
    withCarrotCount(num) {
    this.carrotCount = num;
    return this;
    }
    withBugCount(num) {
    this.bugCount = num;
    return this;
    }
    build() {
    return new Game(this.gameDuration, this.carrotCount, this.bugCount)
    }
}

class Game {
	constructor(gameDuration, carrotCount, bugCount) {
    this.gameDuration = gameDuration;
    this.carrotCount = carrotCount;
    this.bugCount = bugCount;
    .
    .
    .
    }
    
    
const game = new GameBuilder()
// GameBuilder오브젝트가 생성됨
  .withGameDuration(5)
  .withCarrotCount(5)
  .withBugCount(5)
  // 각각 함수에서 return this 하므로 위에서 생성된 Game Builder 오브젝트가 리턴됨
  
  .build();
  //최종적으로 build에서 Game 오브젝트가 리턴됨

}

</script>

클래스 GameBuilder에 return this를 써주면 클래스 자체를 리턴해준다. (메소드마다 return this를 하는 이유)

withGameDuration(duration) {
   this.duration = duration
}

return this를 써놓지 않으면 사람들이 사용할때 일일이 계속 builder.을 반복해서 써야 한다.

const builder = new GameBuilder();
builder.withGameDuration(4);
builder.withCarrotCount(4);

하지만 withGameDuration에서 전달된 duration을 설정하고 그 클래스 자체를 리턴하게 되면 사용하는 곳에서 builder.를 반복해서 호출하지 않아도 된다.

new GameBuilder()
.withGameDuration(4)
.withCarrotCount(4);

따라서 GameBuilder 클래스를 이용해 새로운 인스턴스 game을 만들어서 각 메소드들을 전달해서 정확하게 어떤 의미로 인자를 보내는지 인지하면서 원하는 기능을 실행시킨다.

2. 프로젝트하면서 this 바인딩에 관련된 참고내용

🤓 자바스크립트에서는 클래스에 있는 함수를 누군가에게 전달해줄때는 클래스 정보가 무시된다.(함수를 클래스와 바인딩해줘야함)

class Field{
	this.field.addEventListener("click", this.onClick);
}

이 경우, this는 클래스 정보를 담지 않는다.
자바스크립트에서 this는 동적(누가 호출하느냐에 따라 결정니깐)

✏️ this는 어떤 클래스 안에 있는 함수를 다른 콜백으로 전달할때는 그 함수에 포함 되어있는 클래스의 정보가 사라진다. 그래서 클래스와 이 함수를 묶을 수 있는 this binding을 해야 한다.

<script type="txt/javascript">
	// this binding 하기
    // 3가지 방법
    
    // 1. bind함수 사용
    
    this.onClick = this.onClick.bind(this);
    
    // 2. 화살표함수 사용
    
    this.field.addEventListener("click", (event) => {
    	this.onClick(event);
    })
    
    // 3. 함수를 변수로 만들어주고 화살표 함수로 변경
    
    onClick = (e) => {
    	.
    	.
    	.
    }
    
<script>

위의 방법 중 하나로 this를 바인딩 시키면, onClick은 class와 바인딩되었기 때문에 this.onClick를 전달하게 되었을때 this가 클래스이라는 것을 이제 인지하고 클래스에 등록된 함수라는 걸 알게 된다.

3. 틀리기 쉬운 문자열 고정시키기

함수를 호출할 때 인수를 전달하거나 어떤 문자열을 적용할때 직접 쓰는 문자열은 오타를 만들 수 있다. 그래서 상수로 지정하거나 Object.freeze()를 이용할 수 있다.

export const Reason = Object.freeze({
  win: "win",
  lose: "lose",
  cancel: "cancel",
});

game.setGameStopListener((reason) => {
  let message;
  switch (reason) {
    case Reason.cancel: // 객체의 프로퍼티 사용
      message = "Reply?";
      break;
    case Reason.win: // 객체의 프로퍼티 사용
      message = "YOU WON";
      break;
    case Reason.lose: // 객체의 프로퍼티 사용
      message = "YOU LOST";
      break;
    default:
      throw new Error("not valid reason");
  }
});

출처
드림코딩아카데미 브라우저 101 강의 듣고 적은 내용

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글