TIL_2023_08_16

이종현·2023년 8월 17일
0

Today_I_Learned

목록 보기
83/145
post-thumbnail

Today 요약

  1. 자바스크립트 강의

1. What I Learned?

1.1 자바스크립트 강의

  • 이터러블

    • 이터러블(Iterable)은 자바스크립트에서 순회 가능한 데이터 구조를 의미한다. 이터러블은 내부에 반복 가능한 요소들을 가지고 있으며, 주로 배열, 문자열, 맵(Map), 셋(Set)과 같은 데이터 타입이 이터러블의 예시다. 이터러블은 내부적으로 Symbol.iterator 메서드를 가지고 있으며, 이 메서드를 통해 이터레이터(Iterator)라는 객체를 반환한다. 이터레이터 객체는 next() 메서드를 호출하여 순서대로 다음 요소를 가져올 수 있는 기능을 제공한다. 이러한 내부 메커니즘을 통해 for...of 루프와 같은 반복문에서 이터러블의 요소를 처리한다.
    • 이터레이션 프로토콜은 이터러블 프로토콜을 준수하고 이터러블 프로토콜은 이터레이터 프로콜을 가지고 있으며 이터레이터 프로토콜을 준수한다는 건 next() 메서드를 호출해서 순서대로 다음 요소를 가져올 수 있는 기능을 가지고 있어야 한다.
  • 제너레이터

    • 제너레이터(Generator)는 자바스크립트에서 비동기적인 코드를 작성하고 관리하기 위한 함수다. 제너레이터는 함수의 실행을 일시 중단하고 나중에 다시 시작할 수 있는 기능을 제공하여 비동기 코드를 동기적으로 작성할 수 있도록 도와준다.
    • 제너레이터 함수는 function* 문법으로 정의되며, 함수 내부에서 yield 키워드를 사용하여 값을 반환하고 함수의 실행을 일시 중단할 수 있다. yield 키워드는 제너레이터 함수의 실행을 멈추고 해당 값을 반환한 뒤, 다음 호출 시에는 일시 중단된 위치부터 다시 실행되도록 한다.
    • 함수 표현식으로도 작성이 가능하나, function과 * 키워드가 반드시 있어야 한다. (화살표 함수 표현식은 불가능하다.)
  • Map

    • Map은 키-값 쌍으로 데이터를 저장하는 자료구조입니다. 주로 객체를 사용해야 하는 경우, 키가 문자열인 제약을 피하고 싶을 때 사용된다.
  • Set

    • Set은 중복되지 않는 값들의 집합을 저장하는 자료구조다. 주로 고유한 값들만 저장하고 싶을 때 사용된다.
  • Symbol

    • 심볼(Symbol)은 자바스크립트에서 유일한(unique)하고 변경 불가능한 데이터 타입.
    • 심볼은 주로 객체 프로퍼티의 키로 사용되어 이름 충돌을 방지하거나 내부적으로 사용되는 경우에 활용된다.
    • 심볼의 특징
      • 유일성: 각각의 심볼은 유일하며, 동일한 내용의 심볼을 생성하더라도 엄연히 다른 값으로 취급된다.
      • 변경 ****불가능성: 생성된 후에는 값이 변경되지 않는다.
  • Shortand Properties (간결한 속성 표기법)

    • Shorthand Properties는 객체 리터럴에서 속성 이름과 값이 같은 경우, 속성 이름을 생략하고 값을 직접 할당하는 문법 (최근에 멘토님 피드백 받은 적 있다. { todo: todo} -> { todo } 로 수정)
  • Computed Property Name

    • 객체 리터럴 내에서 속성 이름을 동적으로 계산하여 정의할 수 있는 문법
    • 객체의 속성 이름을 변수 또는 표현식을 사용하여 동적으로 결정할 수 있다.
    const key = 'name'
    const value = 'John'
    
    const person = {
      [key]: value
    }
    
    console.log(person) // { name: 'John' }
  • Lookup Table

    • Computed Property Name을 활용해서 늘어지는 분기문을 효율적으로 관리해주는 자료구조
    • else if 보다는 switch case문, switch case문 보다는 Lookup Table
    function getUserType(type) {
      if (type === 'ADMIN') {
        return '관리자'
      } else if (type === 'INSTRUCTOR') {
        return '강사'
      } else if (type === 'STUDENT') {
        return '수강생'
      } else {
        return '해당 없음'
      }
    }
    function getUserType(type) {
      switch (key) {
        case 'ADMIN':
          return '관리자'
        case 'INSTRUCTOR':
          return '강사'
        case 'STUDENT':
          return '수강생'
        default:
          return '해당 없음'
      }
    }
    function getUserType(type) {
      const USER_TYPE = {
        ADMIN: '관리자',
        INSTRUCTOR: '강사',
        STUDENT: '수강생'
      }
    
      return USER_TYPE[type] || '해당 없음'
    }
  • Object Destructuring

    function Person(name, age, location) {
      this.name = name
      this.age = age
      this.location = location
    }
    
    const poco = new Person('poco', 30, 'korea')

    위 코드의 가장 큰 문제점은 강제된 매개변수들의 순서다. 이럴때 구조 분해 할당이 필요하다.

    function Person({ name, age, location }) {
      this.name = name
      this.age = age
      this.location = location
    }
    
    const poco = new Person({
      location: 'korea',
      name: 'poco',
      age: 30
    })

    아래코드와 같이 필수적으로 넘겨야 하는 것들과 구조 분해 할당으로 넘길 것들을 분리해서 전달할 수도 있다.

    function Person2(name, { age, location }) {
      this.name = name
      this.age = age
      this.location = location
    }
    
    const pocoOptions = {
      age: 30,
      location: 'korea'
    }
    
    const poco2 = new Person2('poco', pocoOptions)

    아래코드 처럼 배열에서 필요한 부분만 구조 분해 하고 싶을 때는 배열 디스트럭처링보다는 객체 디스트럭처링을 이용해서 가지고 오는 것이 더 좋을 수도 있다.

    const orders = ['First', 'Second', 'Third', 'Forth', 'Fifth', 'Sixth']
    
    const st = orders[0]
    const rd = orders[2]
    
    const [first, , , , , sixth] = orders
    
    console.log(first, sixth) // First Sixth
    
    const { 0: first2, 5: sixth2 } = orders
    
    console.log(first2, sixth2) // First Sixth
  • Object.freeze
    객체를 동결시킬 때 주의해야 할 점은 중첩 객체는 동결되지 않는다는 것이다. 이는 얕은 복사때문이다.

    const STATUS = Object.freeze({
      PENDING: 'PENDING',
      SUCCESS: 'SUCCESS',
      FAIL: 'FAIL',
      OPTIONS: {
        GREEN: 'GREEN',
        RED: 'RED'
      }
    })
    
    // 동결이 잘 되었는지 확인하기
    console.log(Object.isFrozen(STATUS)) // true
    console.log(Object.isFrozen(STATUS.SUCCESS)) // true
    console.log(Object.isFrozen(STATUS.OPTIONS)) // false
    
    STATUS.OPTIONS.GREEN = 'blue'
    console.log(STATUS.OPTIONS.GREEN) // blue

    깊은 복사를 하기 위해서는 따로 함수를 만들어서 중첩 객체를 순회해서 동결시켜야 한다.

    function deepFreeze(targetObj) {
      Object.keys(targetObj).forEach((key) => {
        const value = targetObj[key]
        if (typeof value === 'object' && value !== null) {
          deepFreeze(value) // 객체나 배열이면 재귀적으로 동결
        }
      })
    
      return Object.freeze(targetObj)
    }
    
    deepFreeze(STATUS)
    console.log(Object.isFrozen(STATUS.OPTIONS)) // true
    STATUS.OPTIONS.GREEN = 'green'
    console.log(STATUS.OPTIONS.GREEN) // blue

    OPTIONS를 확인해보면 true를 출력하고 기존에 blue로 변경되어있던 GREEN에 값을 green으로 수정해보려고 해도 이번에는 동결이 되어 있기 때문에 수정이 불가능해서 그대로 blue를 출력한다.


profile
데이터리터러시를 중요하게 생각하는 프론트엔드 개발자

0개의 댓글