TIL 👩🏻‍💻

TIL : Modern Javascript Koans

heesue 2021. 4. 8. 23:00

Javascript Koans를 이전 스프린트로 한 적이 있는데 이번에는 Javascript ES6 문법을 익히기 위해 Modern Javascript Koans를 진행했다. 총 4개의 파트로 이루어져 있고 xdescribe로 표시된 pending 테스트까지 25개의 테스트가 존재했다. 시간이 남아서 pending 테스트까지 진행했는데 확실히 다른 부분에 비해 이 부분이 어려웠다.


1. AboutArrowFunction : 화살표 함수

it('화살표 함수 사용법을 익힙니다', function () {
  const add = (x, y) => x + y
  expect(add(20, 30)).to.eql(50)
})
it('화살표 함수를 이용해 클로저를 표현합니다', function () {
  const adder = x => y => x + y
  expect(adder(20)(30)).to.eql(50)
  
  const htmlMaker = tag => textContent => `<${tag}>${textContent}</${tag}>`
  expect(htmlMaker('div')('LILAC')).to.eql('<div>LILAC</div>')
})

2. AboutDestructuring : 구조 분해 할당

it('rest/spread 문법을 배열 분해에 적용할 수 있습니다', () => {
  const array = ['code', 'states', 'im', 'course']
  const [start, ...rest] = array
  expect(start).to.eql('code')
  expect(rest).to.eql(['states', 'im', 'course']) //여러 요소가 있으므로 배열 형태로 나타낸다.
  //할당하기 전 왼쪽에는, rest 문법 이후에 쉼표가 올 수 없다.
  //const [first, ...middle, last] = array
})
it('rest/spread 문법을 객체 분해에 적용할 수 있습니다', () => {
  const user = {
    name: 'A',
    company: {
      name: 'COMPANY',
      department: 'Development',
      role: {
        name: 'Software Engineer'
      }
    },
    age: 35
  }
  
  const changedUser = {
    ...user,
    name: 'B',
    age: 20
  }

  const overwriteChanges = {
    name: 'B',
    age: 20,
    ...user
  }
  
  expect(changedUser).to.eql({
    name: 'B',
    company: {
      name: 'COMPANY',
      department: 'Development',
      role: {
        name: 'Software Engineer'
      }
    },
    age: 20
  })
  
  expect(overwriteChanges).to.eql({
    name: 'A',
    company: {
      name: 'COMPANY',
      department: 'Development',
      role: {
        name: 'Software Engineer'
      }
    },
    age: 35
  })
})

3. AboutThis : this

· 메서드 : 객체의 속성 값으로 담긴 함수 - ex) foo() 함수, foo.bar() 메서드 함수

  (메서드 선언 시 화살표 함수 사용 피하거나, 화살표 함수 사용 시 this 사용 피해야 함.)

· 생성자 : new 키워드를 이용해 호출할 경우에 해당 함수

it('화살표 함수로 작성된 메서드 호출시 this를 확인합니다', () => {
  module.exports.value = 100

  const counter = {
    value: 0,
    increse: () => {
      this.value++
    },
    decrease: () => {
      this.value--
    },
    getValue: () => {
      return this.value
    }
  }

  counter.increse()
  counter.decrease()
  counter.decrease()
  expect(counter.getValue()).to.eql(99)
})

4. AboutFunctionMethods : call, apply, bind

it('call의 두번째 인자 이후로는 파라미터로 전달됩니다', () => {
  function func(name, age, ...args) {
    return `${this.type} ${name} 나이:${age}${args.length === 0 ? '' : ' ' + this.feature + ':' + args.join(',')}`
  }

  const developer = { type: '개발자', feature: '언어' }
  const artist = { type: '아티스트', feature: '노래' }

  expect(func.call(developer, 'A', 35)).to.eql(`개발자 A 나이:35`)
  expect(func.call(developer, 'B', 20, 'JavaScript')).to.eql('개발자 B 나이:20 언어:JavaScript')
  expect(func.call(artist, 'LEE HI', 26, 'Rose', '한숨')).to.eql('아티스트 LEE HI 나이:26 노래:Rose,한숨')
})
it('apply의 두번째 인자는 배열입니다', () => {
  function func(name, age, ...args) {
    return `${this.type} ${name} 나이:${age}${args.length === 0 ? '' : ' ' + this.feature + ':' + args.join(',')}`
  }

  const developer = { type: '개발자', feature: '언어' }
  const artist = { type: '아티스트', feature: '노래' }

  expect(func.call(developer, ['A', 35])).to.eql(`개발자 A 나이:35`)
  expect(func.call(developer, ['B', 20, 'JavaScript'])).to.eql('개발자 B 나이:20 언어:JavaScript')
  expect(func.call(artist, ['LEE HI', 26, 'Rose', '한숨'])).to.eql('아티스트 LEE HI 나이:26 노래:Rose,한숨')
})
it('bind의 인자 순서는 call과 동일합니다', () => {
  const context = 'bind'

  const boundFoo = foo.bind(context, ' is', ' useful')
  expect(boundFoo()).to.eql('bind is useful')
})
it('유사 배열을 다루기에 용이합니다', () => {
  const nodeList = {
    length: 3,
    0: 'div#target',
    1: 'li',
    2: 'span#new'
  };

  expect(Array.prototype.slice.apply(nodeList, [0, 1])).to.eql(['div#target'])
  expect(Array.prototype.map.call(nodeList, node => node.split('#')[0])).to.eql(['div', 'li', 'span'])
  expect(Array.prototype.map.call(nodeList, node => node.split('#'))[0]).to.eql(['div', 'target'])
})

※ 참고 : 조건 (삼항) 연산자

만약 조건이 참이라면, 조건 연산자는 값1을 값으로 갖는다. 그렇지 않은 경우 조건 연산자는 값2를 값으로 갖는다.

조건 ? 값1 : 값2