비구조화 할당

비구조화 할당(destructuring assignment) 구문은 배열 또는 객체에서 데이터를 별개(distinct) 변수로 추출할 수 있게 하는 JavaScript 식(expression)입니다.

구문

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

[a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]

({a, b} = {a:1, b:2});
console.log(a); // 1
console.log(b); // 2

({a, b, ...rest} = {a:1, b:2, c:3, d:4});
//ES7 - Firefox 47a01에서 구현되지 않음

설명

객체 및 배열 리터럴 식은 임시(ad hoc) 데이터 패키지를 만드는 쉬운 방법을 제공합니다.

var x = [1, 2, 3, 4, 5];

비구조화 할당은 비슷한 구문이지만 소스 변수에서 어떤 요소를 추출할지를 정의하는 할당의 좌변에 사용합니다.

var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2

이 능력은 Perl 및 Python 같은 언어에 존재하는 기능과 비슷합니다.

배열 비구조화

기본 변수 할당

var foo = ["one", "two", "three"];

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

선언에서 분리한 할당

변수는 변수 선언에서 분리한 비구조화를 통해 그 값이 할당될 수 있습니다.

var a, b;

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

기본 값

변수는 기본 값이 할당될 수 있습니다, 값을 undefined인 배열에서 가져온 경우에.

var a, b;

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

변수 교환하기

두 변수 값은 비구조화 식 하나로 교환될 수 있습니다.

비구조화 할당이 없으면, 두 변수 교환은 임시 변수 (또는 일부 저-레벨 언어에서는 XOR-swap 트릭) 가 필요합니다.

var a = 1;
var b = 3;

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

함수에서 반환된 배열 구문분석하기

항상 함수에서 배열을 반환할 수 있습니다. 비구조화는 배열 반환 값 작업을 더 간결하게 할 수 있습니다.

이 예제에서, f()는 그 출력으로 값 [1, 2]를 반환하고 비구조화로 한 줄로 구문분석될 수 있습니다.

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

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

일부 반환값 무시하기

다음과 같이 관심 없는 반환값을 무시할 수 있습니다:

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

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

다음과 같이 모든 반환값을 무시할 수도 있습니다:

[,,] = f();

일치하는 정규식에서 값 가져오기

정규식 exec() 메서드가 일치를 발견하면, 먼저 문자열의 전체 일치하는 부분과 그 뒤에 정규식의 괄호로 묶인 각 그룹과 일치된 문자열 부분을 포함하는 배열을 반환합니다. 비구조화 할당은 이 배열에서 그 부분을 쉽게 빼올 수 있습니다, 필요하지 않은 경우에 전체 일치를 무시하면서.

var url = "https://developer.mozilla.org/en-US/Web/JavaScript";

var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

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

console.log(protocol); // "https"

객체 비구조화

기본 할당

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

console.log(p); // 42
console.log(q); // true

선언 없는 할당

변수는 선언에서 분리한 비구조화로 그 값이 할당될 수 있습니다.

var a, b;

({a, b} = {a:1, b:2});

할당 문을 둘러싼 ( .. )는 선언 없이 객체 리터럴 비구조화 할당을 사용할 때 필요한 구문입니다.

{a, b} = {a:1, b:2}는 유효한 독립 구문이 아닙니다, 좌변의 {a, b}이 블록으로 간주되고 객체 리터럴이 아니기에.

그러나, ({a, b} = {a:1, b:2})는 유효합니다, var {a, b} = {a:1, b:2}이기에

새로운 변수 이름에 할당하기

변수는 객체에서 추출되고 객체 속성과 다른 이름인 변수에 할당될 수 있습니다.

var o = {p: 42, q: true};
var {p: foo, q: bar} = o;

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

기본 값

변수는 기본값이 할당될 수 있습니다, 값을 undefined인 객체에서 가져온 경우에.

var {a=10, b=5} = {a: 3};

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

함수 매개변수의 기본 값 설정하기

ES5 버전

function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? 'big' : options.size;
  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
  // 이제 드디어 몇 가지 차트 그리기 수행
}

drawES5Chart({
  cords: { x: 18, y: 30 },
  radius: 30
});

ES6 버전

function drawES6Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
  console.log(size, cords, radius);
  // 몇 가지 차트 그리기 수행
}

// Firefox에서, 비구조화 할당을 위한 기본 값은 아직 구현되지 않음 (아래 설명된 대로).
// 해결책은 다음 방법으로 매개변수를 작성하는 것임:
// ({size: size = 'big', cords: cords = { x: 0, y: 0 }, radius: radius = 25} = {})

drawES6Chart({
  cords: { x: 18, y: 30 },
  radius: 30
});

Firefox에서, 비구조화 할당을 위한 기본 값은 아직 구현되지 않았습니다: var { x = 3 } = {} 및 var [foo = "bar"] = []. 함수의 비구조화된 기본 값에 대한 bug 932080 참조.

모듈 (ES6 아닌) 로딩

비구조화는 여기처럼 Add-on SDK의 비ES6 모듈의 특정 하위집합 로드를 도울 수 있습니다:

const { Loader, main } = require('toolkit/loader');

ES6의 import 문은 비구조화와 비슷하게 동작하지만 실제로는 비구조화가 아닌 게 중요합니다.

중첩 객체 및 배열 비구조화

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"

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",
      brother: "Howard Jones"
    },
    age: 25
  }
];

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"

함수 매개변수로 전달된 객체에서 필드 가져오기

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"

이 예제는 사용자 객체에서 id, displayNamefirstName 을 가져와 출력합니다.

객체 속성 계산명 및 비구조화

속성 계산명(computed property name)은, 객체 리터럴에 붙은 것 같은, 비구조화에 사용될 수 있습니다.

let key = "z";
let { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"

스펙

스펙 상태 설명
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Destructuring assignment' in that specification.
Standard 초기 정의.
ECMAScript 2017 Draft (ECMA-262)
The definition of 'Destructuring assignment' in that specification.
Draft  

브라우저 호환성

Feature Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Basic support 49.0 2.0 (1.8.1) 14[1] No support No support 7.1
Computed property names 49.0 34 (34) 14[1] No support No support No support
Spread operator 49.0 34 (34) 12[1] ? ? ?
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support No support 49.0 1.0 (1.0) No support No support 8 49.0
Computed property names No support 49.0 34.0 (34) No support No support No support 49.0
Spread operator No support 49.0 34.0 (34) ? ? ? 49.0

[1] `about:flags` 아래 활성화되는 "Enable experimental Javascript features" 필요

Firefox 전용 주의사항

  • Firefox는 JS1.7에서 비구조화 용 비표준 언어 확장을 제공합니다. 이 확장은 Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37)에서 제거되었습니다. bug 1083498 참조.
  • Gecko 41 (Firefox 41 / Thunderbird 41 / SeaMonkey 2.38)을 시작으로 ES6 스펙를 따르기 위해, ([a, b]) = [1, 2] 또는 ({a, b}) = { a: 1, b: 2 } 같은 괄호 묶인 비구조화 패턴은 이제 유효하지 않은 것으로 간주되고 SyntaxError 가 발생(throw)합니다. 자세한 사항은 Jeff Walden의 블로그 게시글bug 1146136 참조.

참조

문서 태그 및 공헌자

 이 페이지의 공헌자: Netaras
 최종 변경: Netaras,