개발

자바스크립트 객체 리터럴을 이용한 스위치문 구현

동고킴 2021. 12. 4. 12:20
반응형

 

 

자바스크립트의 스위치(swtich)문을 객체 리터럴(object literal)을 이용하여 구현해보자.

 

객체 리터럴로 스위치문을 대체하기 위해서는 먼저 ES6의 객체 리터럴 확장 기능을 알아야한다. 먼저 ES6의 객체 리터럴을 정리하고 스위치문을 구현해보자.

 

1) ES6 객체 리터럴 확장 기능

1-1) 객체 생성 시, 속성을 축약할 수 있다.

객체 생성 시, 변수만 설정해주면 된다. ES6 이전에는 객체 리터럴이 key, value 쌍이었다. 예를 들어

let name = 'ES5'
let stauts = "active"
let server = {
  no: 1,
  name: name,
  status: stauts,
}
console.log(server)

 

{ no: 1, name: 'ES5', status: 'active' }

 

ES6에서는 아래처럼 할 수 있다.

let name = 'ES6'
let stauts = "active"
let server = {
  no: 1,
  name,
  stauts,
}
console.log(server)

 

{ no: 1, name: 'ES6', stauts: 'active' }

 

1-2) 객체 key에 계산식 및 템플릿 리터럴을 사용할 수 있다.

ES6에서는 아래처럼 객체 key에서 속성을 계산할 수 있고 템플릿 리터럴을 사용할 수 있다.

let name = 'server name'
let one = 1
let two = 2
let server = {
  [name]: 'ES6',
  [one + two]: 'one two',
  [`${one} server`]: 9999,
}
console.log(server)

 

{ 3: 'one two', 'server name': 'ES6', '1 server': 9999 }

 

1-3) 함수 생성이 간결해졌다.

ES6 이전에는 객체 리터럴에 대한 메서드를 정의할 떄 function 키워드를 사용하여 이름과 전체 함수 정의를 지정해야했다.

let server = {
  name: 'ES5',
  restart: function() {
    console.log("The " + this.name + " is restarting...")
  }
}
server.restart()

 

The ES5 is restarting... 

 

ES6에서는 function를 제거하여 객체 리터럴의 함수 구문을 보다 간결하게 만든다. 그리도 key에 공백도 사용할 수 있다.

let server = {
  name: 'ES6',
  restart() {
    console.log("The " + this.name + " is restarting...")
  },
  'starting up'() {
    console.log("The " + this.name + " is starting up!")
  },
}
server.restart()
server["starting up"]()

 

The ES6 is restarting... 
The ES6 is starting up! 

 

2) switch문 구현

이제 switch문을 객체 리터럴로 구현해보자. 순서대로 하나씩 진행한다.

let fruit = 'oranges';

switch (fruit) {
  case 'apples':
    console.log('Apples');
    break;
  case 'oranges':
    console.log('Oranges');
    break;
}
// Logs: 'Oranges'

const logFruit = {
  'apples': () => console.log('Apples'),
  'oranges': () => console.log('Oranges')
};

logFruit[fruit](); // Logs: 'Oranges'

 

이것은 훨씬 더 읽기 쉽고 덜 장황하다 그러나 아직 default를 처리하지 않았다. 이를 처리하기 위해 'default' 키를 추가 하고 표현식의 값이 객체에 존재하는지 확인할 수 있다.

let fruit = 'strawberries';

switch (fruit) {
  case 'apples':
    console.log('Apples');
    break;
  case 'oranges':
    console.log('Oranges');
    break;
  default:
    console.log('Unknown fruit');
}
// Logs: 'Unknown fruit'

const logFruit = {
  'apples': () => console.log('Apples'),
  'oranges': () => console.log('Oranges'),
  'default': () => console.log('Unknown fruit')
};

(logFruit[fruit] || logFruit['default'])(); // Logs: 'Unknown fruit'

 

이제 break문 이 없을 때 일어나는 케이스를 처리한다. 이것은 단순히 객체 리터럴에서 논리를 추출하고 재사용하는 문제이다. 키 별로 함수를 실행한다.

let fruit = 'oranges';

switch (fruit) {
  case 'apples':
  case 'oranges':
    console.log('Known fruit');
    break;
  default:
    console.log('Unknown fruit');
}
// Logs: 'Known fruit'

const knownFruit = () => console.log('Known fruit');
const unknownFruit = () => console.log('Unknown fruit');

const logFruit = {
  'apples': knownFruit,
  'oranges': knownFruit,
  'default': unknownFruit
};

(logFruit[fruit] || logFruit['default'])(); // Logs: 'Known fruit'

 

마지막으로 코드를 재사용 가능한 간단한 함수로 추출한다. (default 케이스에 대한 조회 개체와 선택적 이름을 제공)

const switchFn = (lookupObject, defaultCase = 'default') =>
  expression => (lookupObject[expression] || lookupObject[defaultCase])();

const knownFruit = () => console.log('Known fruit');
const unknownFruit = () => console.log('Unknown fruit');

const logFruit = {
  'apples': knownFruit,
  'oranges': knownFruit,
  'default': unknownFruit
};

const fruitSwitch = switchFn(logFruit, 'default');

fruitSwitch('apples'); // Logs: 'Known fruit'
fruitSwitch('pineapples'); // Logs: 'Unknown fruit'

 

참고

반응형