화살표 함수로 복잡도를 낮춰라

해체 할당을 적극 활용하자!

const getFullName = ({ first, last }) => ({ first, last });

console.log(getFullName({ first: "wayne", last: "kim" }));

 

화살표 함수로 고차 함수를 만들어 사용하자.

const getAPI = (host) => {
  return (path) => {
    return `${host}/${path}`;
  };
};

const hostGet = getAPI("www.myhome.com");
console.log(hostGet("board"));
console.log(hostGet("user"));

 

인수가 많은 함수 인수를 부분 적용 함수로 단순화 하자.

부분 적용 함수를 만들자. 고차 함수와 클로저를 이용하면 된다!

 

n개의 인수를 받던 함수를 m개의 인수를 넣어 n-m개를 인수를 받는 함수를 반환하는 함수... ( 그냥 소스 코드를 보자 )

 

특정 인수는 고정적이고 특정 인수는 고정적이지 않을 때 유용합니다.

const address1 = {
  state: "서울시",
  city: "관악구",
  line1: "관악로",
  line2: "1",
};

const address2 = {
  state: "Seoul",
  city: "Mapo-gu",
  line1: "World Cup buk-ro",
  line2: "1",
};

const getAddressFormatKorean = ({ state, city, line1, line2 }) =>
  `${state} ${city} ${line1} ${line2}`;

console.log(getAddressFormatKorean(address1));

let getAddressFormatAmerica = ({ state }) => ({ city, line1, line2 }) =>
  `${line2}, ${line1}, ${city}, ${state}`;

const getAddressFormatAmerica2 = getAddressFormatAmerica(address2);
console.log(getAddressFormatAmerica2(address2));

 

커링 함수

특정 인수는 고정적이고 특정 인수는 고정적이지 않을 때 유용합니다.

const address2 = {
  state: "Seoul",
  city: "Mapo-gu",
  line1: "World Cup buk-ro",
  line2: "1",
};

let getAddressFormatAmerica = ({ state }) => ({ city }) => ({ line1 }) => ({
  line2,
}) => `${line2}, ${line1}, ${city}, ${state}`;

const getAddressState = getAddressFormatAmerica(address2);
const getAddressStateCity = getAddressState(address2);
const getAddressStateCityLine1 = getAddressStateCity(address2);
const strAddressStateCityLine1Line2 = getAddressStateCityLine1(address2);

console.log(strAddressStateCityLine1Line2);

 

화살표 함수로 문맥 혼동을 피하자

정적언어에 비해서 자바스크립트는 동적언어 이기 때문에 문맥(this)을 파악하는 건 어렵다. 문맥을 지정하지 않는 이상 this는 현재 스코프 내에서 가장 가까운 객체를 가르킵니다. 다만, 일반적인 함수를 콜백 함수로 사용할 경우 특정 객체가 가진 메소드가 아니므로 this는 전역객체가 됩니다. setTimeout, setInterval, map, filter 등등 사용할 때면 주의가 필요합니다. 화살표 함수는 이런 번거로운 문맥 바인딩 작업을 간소화 합니다.

 

class Message {
  constructor(msg) {
    this.msg = msg;
    this.oneSecond = 1000;
  }

  showMessageLater(second) {
    setTimeout(
      function () {
        console.log(this.msg);
      }.bind(this),
      second * this.oneSecond
    );
  }
  showMessageLater2(second) {
    setTimeout(() => console.log(this.msg), second * this.oneSecond);
  }
}

const msgAlert = new Message("경고!");
msgAlert.showMessageLater(1);
msgAlert.showMessageLater2(2);

 

읽기 쉬운 클래스 만듭시다!

자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어 입니다. ES6 부터는 클래스 키워드로 객체를 생성 할 수 있습니다. class 키워드로 완전히 정적인 객체 지향 프로그래밍 언어와 동일하게 작동하기 바라는 것은 큰 욕심 입니다. 클래스 키워드로 인해서 프로토타입 기반 언어의 자연스러운 부분이 왜곡되지만 충분히 훌룡한 기능을 합니다. 다수의 개발자가 이해하기 쉬운 코드가 더 좋은 것 입니다.

 

class Coin {
  constructor(count, date) {
    this.count = count | 0;

    const year = new Date().getFullYear();
    this.expirationDate = date || new Date(year, 12, "");
  }
  use(count = 1) {
    //으아 더러워~
    const today = new Date();
    if (today < this.expirationDate && this.count > 0) {
      this.count = this.count - count;
    } else {
      throw new Error("코인 없음");
    }
  }
  getCount() {
    return this.count;
  }
}

const myCoin = new Coin(10);
myCoin.use(5);
myCoin.use(5);
myCoin.use(5);

 

생성자의 역할은 this 문맥을 생성하고 속성을 추가하는 것 입니다. 속성은 현재 public 지정자만 지원합니다. TC39에서 private은 고려 중 입니다. 무엇보다 프로토타입 보다 인터페이스가 직관적 입니다.

 

각 함수는 prototype 속성이 있습니다. 이 속성에 메소드를 추가하여 링크시켜 인스턴스는 이 메소드를 사용합니다. 클래스 기반 객체지향 언어와 다른 부분이 이러한 점 입니다. 위 작업은 간단하게 하는 것이므로 자바스크립트에서 class는 문법적 설탕 입니다.

 

상속으로 메소드를 공유합시다

프로토타입으로 상속을 구현할 경우, 복잡하며 직관적이지 않은 문제가 있습니다. 그러므로 extends 적극 활용합시다! 지나친 상속은 비대한 코드로 이어지는 경우가 많습니다. 적당한 상속을 합시다!

 

get과 set으로 인터페이스 단순화합시다

게터 또는 세터는 함수를 속성처럼 보이게 해서 복잡성을 숨기는 방법 입니다.

 

비공개 속성은 자바스크립트 코트 컨벤션인 밑줄을 입력해 메소드 또는 속성을 비공개라는 점을 표시합니다. 그리고 게터 또는 세터를 사용합니다.

 

복잡한 데이터 구조를 간단한 배열처럼 쉽게 다루기

제너레이터는 호출되었을 때 그 즉시 끝까지 실행하지 않고 중간에 빠져나갔다가 다시 돌아올 수 있는 함수 입니다.

 

function* getName() {
  yield "wayne";
  yield "eunchan";
}

const name = getName();

console.log(name.next()); //{ value: 'wayne', done: false }
console.log(name.next()); //{ value: 'eunchan', done: false }
console.log(name.next()); //{ value: undefined, done: true }
function* stepGuide() {
  yield () => console.log("안내 시작");
  yield () => console.log("안내 1");
  yield () => console.log("안내 2");
  yield () => console.log("안내 3");
  yield () => console.log("안내 완료");
}

for (const step of stepGuide()) {
  step();
}

 

복잡한 데이터 구조 또는 흐름을 다뤄야하는 부담을 다른 개발자에게 주고 싶지 않다면, 제너레이터가 훌륭한 해결책이 됩니다?!

 

문맥 설정은 bind()

생성자 내에서 메소드의 this를 바인딩하여 메소드를 원래 위치에 그대로 유지합시다.

 

 

블로그 이미지

_김은찬

두번 다시는 꺾이지 않으리

,