비구조화 할당(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, displayName 및 firstName 을 가져와 출력합니다.
객체 속성 계산명 및 비구조화
속성 계산명(computed property name)은, 객체 리터럴에 붙은 것 같은, 비구조화에 사용될 수 있습니다.
let key = "z";
let { [key]: foo } = { z: "bar" };
console.log(foo); // "bar"
스펙
브라우저 호환성
| 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 참조.