Post

[모던 자바스크립트 Deep Dive]36장 디스트럭처링 할당

36.1 배열 디스트럭처링 할당

  • ES5에서 할당하던 방법

    1
    2
    3
    4
    5
    6
    7
    8
    
      // ES5
      var arr = [1, 2, 3];
        
      var one   = arr[0];
      var two   = arr[1];
      var three = arr[2];
        
      console.log(one, two, three); // 1 2 3
    
  • ES6의 배열 구조 분해 할당

    1
    2
    3
    4
    5
    6
    7
    8
    
      const arr = [1, 2, 3];
        
      // ES6 배열 디스트럭처링 할당
      // 변수 one, two, three를 선언하고 배열 arr을 디스트럭처링하여 할당한다.
      // 이때 할당 기준은 배열의 인덱스다.
      const [one, two, three] = arr;
        
      console.log(one, two, three); // 1 2 3
    
    • 할당문의 좌변: 값을 할당받을 변수
      • 변수는 배열 리터럴 형태로 선언한다.

        1
        
          const [x, y] = [1, 2];
        
    • 할당문의 우변: 할당의 대상이 되는 이터러블
      • 우변에 이터러블을 할당하지 않으면 에러 발생

        1
        2
        3
        4
        
          const [x, y]; 
          // SyntaxError: Missing initializer in destructuring declaration
                    
          const [a, b] = {}; // TypeError: {} is not iterable
        
    • 할당 기준은 배열의 인덱스 ⇒ 즉 순서대로 할당된다.
      • 변수의 개수와 이터러블의 요소 개수가 일치하지 않아도 된다.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        
          const [a, b] = [1, 2];
          console.log(a, b); // 1 2
                    
          const [c, d] = [1];
          console.log(c, d); // 1 undefined
                    
          const [e, f] = [1, 2, 3];
          console.log(e, f); // 1 2
                    
          const [g, , h] = [1, 2, 3];
          console.log(g, h); // 1 3
        
  • 배열 구조 분해 할당의 변수 선언문은 선언과 할당 분리 가능

    1
    2
    
      let x, y;
      [x, y] = [1, 2];
    
    • 이 경우 const 키워드로 변수를 선언할 수 없기 때문에 권장하지 않음
  • 배열 구조 분해 할당을 위한 변수에 기본값을 설정 가능

    1
    2
    3
    4
    5
    6
    7
    
      // 기본값
      const [a, b, c = 3] = [1, 2];
      console.log(a, b, c); // 1 2 3
        
      // 기본값보다 할당된 값이 우선한다.
      const [e, f = 10, g = 3] = [1, 2];
      console.log(e, f, g); // 1 2 3
    
  • 배열과 같은 이터러블에서 필요한 요소만 추출하여 변수에 할당할 때 유용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
      // url을 파싱하여 protocol, host, path 프로퍼티를 갖는 객체를 생성해 반환한다.
      function parseURL(url = '') {
        // '://' 앞의 문자열(protocol)과 '/' 이전의 '/'으로 시작하지 않는 문자열(host)과 
      	// '/' 이후의 문자열(path)을 검색한다.
        const parsedURL = url.match(/^(\w+):\/\/([^/]+)\/(.*)$/);
        console.log(parsedURL);
        /*
        [
          'https://developer.mozilla.org/ko/docs/Web/JavaScript',
          'https',
          'developer.mozilla.org',
          'ko/docs/Web/JavaScript',
          index: 0,
          input: 'https://developer.mozilla.org/ko/docs/Web/JavaScript',
          groups: undefined
        ]
        */
        
        if (!parsedURL) return {};
        
        // 배열 디스트럭처링 할당을 사용하여 이터러블에서 필요한 요소만 추출한다.
        const [, protocol, host, path] = parsedURL;
        return { protocol, host, path };
      }
        
      const parsedURL = parseURL('https://developer.mozilla.org/ko/docs/Web/JavaScript');
      console.log(parsedURL);
      /*
      {
        protocol: 'https',
        host: 'developer.mozilla.org',
        path: 'ko/docs/Web/JavaScript'
      }
      */
    
  • 배열 구조 분해 할당을 위한 변수에 Rest 요소 ...을 사용 가능

    • Rest 요소는 Rest 파라미터처럼 반드시 마지막에 위치
    1
    2
    3
    
      // Rest 요소
      const [x, ...y] = [1, 2, 3];
      console.log(x, y); // 1 [ 2, 3 ]
    

36.2 객체 디스트럭처링 할당

  • ES5에서 할당하던 방법

    1
    2
    3
    4
    5
    6
    7
    
      // ES5
      var user = { firstName: 'Ungmo', lastName: 'Lee' };
        
      var firstName = user.firstName;
      var lastName  = user.lastName;
        
      console.log(firstName, lastName); // Ungmo Lee
    
  • ES6의 배열 구조 분해 할당
    • 할당문의 좌변: 값을 할당받을 변수
      • 변수는 객체 리터럴 형태로 선언한다.

        1
        
          const { lastName, firstName } = { firstName: 'Ungmo', lastName: 'Lee' };
        
    • 할당문의 우변: 할당의 대상이 되는 객체
      • 객체 또는 객체로 평가될 수 있는 표현식을 할당하지 않는 경우 에러 발생

        1
        2
        3
        4
        5
        
          const { lastName, firstName };
          // SyntaxError: Missing initializer in destructuring declaration
                    
          const { lastName, firstName } = null;
          // TypeError: Cannot destructure property 'lastName' of 'null' as it is null.
        
    • 할당 기준은 프로퍼티 키 ⇒ 즉 선언된 변수의 이름과 프로퍼티 키가 일치하면 할당

      1
      2
      3
      4
      5
      6
      7
      8
      
        const user = { firstName: 'Ungmo', lastName: 'Lee' };
              
        // ES6 객체 디스트럭처링 할당
        // 변수 lastName, firstName을 선언하고 user 객체를 디스트럭처링하여 할당한다.
        // 이때 프로퍼티 키를 기준으로 디스트럭처링 할당이 이루어진다. 순서는 의미가 없다.
        const { lastName, firstName } = user;
              
        console.log(firstName, lastName); // Ungmo Lee
      
  • 객체의 프로퍼티 키와 다른 변수 이름으로 할당받는 경우

    1
    2
    3
    4
    5
    6
    7
    8
    
      const user = { firstName: 'Ungmo', lastName: 'Lee' };
        
      // 프로퍼티 키를 기준으로 디스트럭처링 할당이 이루어진다.
      // 프로퍼티 키가 lastName인 프로퍼티 값을 ln에 할당하고,
      // 프로퍼티 키가 firstName인 프로퍼티 값을 fn에 할당한다.
      const { lastName: ln, firstName: fn } = user;
        
      console.log(fn, ln); // Ungmo Lee
    
    • 참고) 프로퍼티 축약 표현

      1
      2
      3
      
        const { lastName, firstName } = user;
        // 위와 아래는 동치다.
        const { lastName: lastName, firstName: firstName } = user;
      
  • 객체 구조 분해 할당을 위한 변수에 기본값 설정 가능

    1
    2
    3
    4
    5
    
      const { firstName = 'Ungmo', lastName } = { lastName: 'Lee' };
      console.log(firstName, lastName); // Ungmo Lee
        
      const { firstName: fn = 'Ungmo', lastName: ln } = { lastName: 'Lee' };
      console.log(fn, ln); // Ungmo Lee
    
  • 객체에서 프로퍼티 키로 필요한 값만 추출하여 변수에 할당할 때 유용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      const str = 'Hello';
      // String 래퍼 객체로부터 length 프로퍼티만 추출한다.
      const { length } = str;
      console.log(length); // 5
        
      const todo = { id: 1, content: 'HTML', completed: true };
      // todo 객체로부터 id 프로퍼티만 추출한다.
      const { id } = todo;
      console.log(id); // 1
    
  • 객체를 인수로 전달받는 함수의 매개변수에도 사용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    
      // 객체 구조 분해 할당 적용 전
        
      function printTodo(todo) {
        console.log(`할일 ${todo.content}${todo.completed ? '완료' : '비완료'} 상태입니다.`);
      }
        
      printTodo({ id: 1, content: 'HTML', completed: true });
      // 할일 HTML은 완료 상태입니다.
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      // 객체 구조 분해 할당 적용 전
      // 좀 더 간단하고 가독성 좋은 표현 가능
        
      function printTodo({ content, completed }) {
        console.log(`할일 ${content}${completed ? '완료' : '비완료'} 상태입니다.`);
      }
        
      printTodo({ id: 1, content: 'HTML', completed: true });
      // 할일 HTML은 완료 상태입니다.
    
  • 배열의 요소가 객체인 경우 배열 구조 분해 할당과 객체 구조 분해 할당 혼용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      const todos = [
        { id: 1, content: 'HTML', completed: true },
        { id: 2, content: 'CSS', completed: false },
        { id: 3, content: 'JS', completed: false }
      ];
        
      // todos 배열의 두 번째 요소인 객체로부터 id 프로퍼티만 추출한다.
      const [, { id }] = todos;
      console.log(id); // 2
    
  • 중첩 객체에 객체 구조 분해 할당을 사용하는 경우

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      const user = {
        name: 'Lee',
        address: {
          zipCode: '03068',
          city: 'Seoul'
        }
      };
        
      // address 프로퍼티 키로 객체를 추출하고 이 객체의 city 프로퍼티 키로 값을 추출한다.
      const { address: { city } } = user;
      console.log(city); // 'Seoul'
    
  • 객체 구조 분해 할당을 위한 변수에 Rest 프로퍼티 ...을 사용 가능
    • Rest 요소는 Rest 파라미터처럼 반드시 마지막에 위치
    1
    2
    3
    
      // Rest 프로퍼티
      const { x, ...rest } = { x: 1, y: 2, z: 3 };
      console.log(x, rest); // 1 { y: 2, z: 3 }
    
This post is licensed under CC BY 4.0 by the author.