비구조화 할당(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 참조.