구조 분해 (destructing)

Sang heon lee·2021년 6월 29일

1. 구문

  • 배열
var a,b,rest;
[a,b] = [10,20]
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
  • 객체 (중요!!!!)
    - key 값을 따라가며 순서(rest 제외)는 상관없다.
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

({f, g, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(f); // undefined
console.log(g); // undefined

({b, a, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(b); // 20
console.log(a); // 10

2. 설명

  • 구조 분해 할당은 할당문의 좌변에서 사용하여, 원래 변수에서 어떤 값을 분해해 할당할지 정의합니다.
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2

3. 배열 구조 분해

3.1 기본 변수 할당

var foo = ["one", "two", "three"];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

만약 var one, two, three = foo; 할시
console.log(one); // undefined
console.log(two); // undefined
console.log(three); // ["one", "two", "three"]

3.2 선언에서 분리한 할당

  • 변수의 선언이 분리되어도 구조 분해를 통해 값을 할당할 수 있습니다.
var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

3.3 기본값

  • 변수에 기본값을 할당하면, 분해한 값이 undefined일 때 그 값을 대신 사용합니다.
var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

3.4 변수 값 교환하기

  • 하나의 구조 분해 표현식만으로 두 변수의 값을 교환할 수 있습니다.
  • 구조 분해 할당 없이 두 값을 교환하려면 임시 변수가 필요합니다.
var a = 1;
var b = 3;

[a, b] = [b, a]
console.log(a); // 3
console.log(b); // 1

3.5 함수가 반환한 배열 분석

  • 함수는 이전부터 배열을 반환할 수 있었습니다. 구조 분해를 사용하면 반환된 배열에 대한 작업을 더 간결하게 수행할 수 있습니다.
function f(){
  return [1,2];
}

var a,b
[a,b] = f()
console.log(a) // 1
console.log(b) // 2

3.6 일부 반환 값 무시하기

function f(){
  return [1,2,3]
}

var [a, ,b] = f()
console.log(a) // 1
console.log(b) // 3

3.7 변수에 배열의 나머지를 할당하기

  • 배열을 구조 분해할 경우, 나머지 구문을 이용해 분해하고 남은 부분을 하나의 변수에 할당할 수 있습니다.
var [a, ...b] = [1,2,3]
console.log(a) // 1
console.log(b) // [2,3]

var [a, b, ...c] = [1,2,3]
console.log(a) // 1
console.log(b) // 2
console.log(c) // [3]

3.8 정규 표현식과 일치하는 값 해체하기

  • 정규 표현식의 exec() 메서드는 일치하는 부분을 찾으면 그 문자열에서 정규식과 일치하는 부분 전체를 배열의 맨 앞에, 그리고 그 뒤에 정규식에서 괄호로 묶인 각 그룹과 일치하는 부분을 포함하는 배열을 반환합니다. 구조 분해 할당은 필요하지 않은 경우 일치하는 전체 부분은 무시하고 필요한 부분만 쉽게 뺴올 수 있습니다.
function parseProtocol(url) {
  var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

  var [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"

4. 객체 구조 분해

4.1 기본 할당 (매번 잊는 부분)

var obj = {p:42, q:true}
var {p, q} = obj;

console.log(p); // 42
console.log(q); // true
  • 아래 예시처럼 키값과 다른 변수명은 안된다!
var obj = {p:42, q:true}
var {a, b} = obj;     

console.log(a); // undefined
console.log(b); // undefined

4.2 선언 없는 할당 (실수 하기 좋은 부분)

var a, b;

({a, b} = {a: 1, b: 2});
  • 할당 문을 둘러싼 ( .. )는 선언 없이 객체 리터럴(object literal) 비구조화 할당을 사용할 때 필요한 구문입니다.

  • {a, b} = {a:1, b:2}는 유효한 독립 구문이 아닙니다. 좌변의 {a, b}이 객체 리터럴이 아닌 블록(?)으로 간주되기 때문입니다.
    하지만, ({a, b} = {a:1, b:2})는 유효한데, var {a, b} = {a:1, b:2}와 같습니다.

  • ( .. ) 표현식 앞에는 세미콜론이 있어야 합니다. 그렇지 않을 경우 이전 줄과 연결되어 함수를 실행하는데 이용될 수 있습니다.

4.3 새로운 변수 이름으로 할당하기 ⭐️⭐️⭐️

  • 객체로부터 속성을 해체하여 객체의 원래 속성명과는 다른 이름의 변수에 할당할 수 있습니다.
var obj = {p:42, q:true};
var {p:foo, q:bar} = obj

console.log(foo) // 42
console.log(bar) // true

4.4 기본값

  • 객체로부터 해체된 값이 undefined인 경우, 변수에 기본값을 할당할 수 있습니다.
var {a=10, b=5} = {a:3};

console.log(a) // 3
console.log(b) // 5

4.5 기본값 갖는 새로운 이름의 변수에 할당하기

var { a: aa=5 b:bb=5} = {a:3};

console.log(aa); // 3
console.log(bb); // 5

4.6 중첩된 객체 및 배열의 구조 분해 ⭐️⭐️⭐️

var metadata = {
  title : "Scratchpad"
  translations : [
    {
      locale : "de",
      localization_tags : [],
      last_edit : "2014-04-14T08:43:37",
      url : "/de/docs/Tools/Scratchpad"
      title : "JavaScript-Umgebung"
    } ],
  url : "/en-US/docs/Tools/Scratchpad"
};

var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"

4.7 for of 반복문과 구조 분해 ⭐️⭐️⭐️

var people = [
  {
    name : 'Mike Smith',
    family : {
      mother : 'Jane Smith',
      father : 'Harry Smith',
      sister : 'Samantha Smith'
    },
    age : 35
  },
  {
    name : 'Tom Jones',
    family : {
      mother : 'Norah Jones',
      father : 'Richard Jones',
      sister : 'Howard Jones'
    },
    age : 35
  }
  ];
  
  for (var {name: n, family: { father: f } } of people) {
  console.log('Name: ' + n + ', Father: ' + f);
}

// 'Name: Mike Smith, Father: Harry Smith'
// 'Name: Tom Jones, Father: Richard Jones'

4.8 함수 매개변수로 전달된 객체에서 필드 해체하기 ⭐️⭐️⭐️

function userId({id}){
  return id;
}

function whois({displayName : displayName, fullName : {firstName : name}}){
  console.log(displayName + ' is ' + name);
}

var user = {
  id : 42,
  displayName : 'jdoe',
  fullName : {
    firstName : 'John',
    lastName : 'Doe'
  }
};

console.log('userId: ' + userId(user); // 'userId: 42"
whois(user) // 'jdoe is John'

4.9 계산된 속성 이름과 구조 분해 ⭐️⭐️⭐️

  • 계산된 속성 이름(computed property name)은 객체 리터럴과 비슷하게 구조 분해에도 사용될 수 있습니다.
let key = 'z';
let { [key]:foo} = {z:'bar'};

console.log(foo) // 'bar'

4.10 객체 구조 분해에서 Rest

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }

4.11 속성 이름이 유효한 JavaScript 식별자명이 아닌 경우

  • 구조 분해는 JavaScript 식별자 이름으로 적합하지 않은 속성명이 제공된 경우에도 이용할 수 있습니다. 이 때는 유효한 식별자명을 제공해야 합니다.
const foo = {'fizz-buzz':true};
const {'fizz-buzz':fizzBuzz} = foo;

console.log(fizzBuzz) // true
profile
개초보

0개의 댓글