일.목표
객체 또는 배열에서 값을 가져와 다른 변수에 할당하려면, 이전에는 이렇게 해야 했습니다:
var arr = [1, 2, 3, 4];
var first = arr[0];
var senond = arr[1];
var third = arr[3];
배열을 분해하여 요소 값을 가져오고, 할당합니다. 위의 과정은: 분해 - 할당입니다
ES6 는 새로운 개념을 제안했습니다:destructuring(구조 분해 할당), 위의 프로세스에 더 나은 가독성을 갖게 하고, "하드코딩" 스타일의 코드를 회피할 수 있습니다
이.iterable 구조 분해 할당
var/let/const [var1, var2...] = iterable 구문은 변수 선언과 동시에 배열/이터레이터 구조 분해 할당을 수행하는 것을 나타냅니다
분해되는 값은 iterable 이어야 합니다. 제네레이터 구문을 통해 커스텀 오브젝트를 쉽게 iterable 로 만들 수 있습니다 ([암우경양:for…of 루프_ES6 노트 1](/articles/for-of 循环-es6 笔记 1/#articleHeader5) 참조). iterable 구조 분해 할당의 특징은 다음과 같습니다:
-
임의의 깊이의 중첩 배열에 대해 구조 분해 할당 가능
-
빈 자리를 남겨 특정 요소를 스킵 가능
-
가변 길이 인자 (
...var구문, 상세는 [암우경양:기본 파라미터와 가변 길이 인자_ES6 노트 4](/articles/默认参数和不定参数-es6 笔记 4/) 참조) 를 사용하여 나머지 모든 요소를 캡처 가능
예를 들어:
// 배열
var [[first, [second]], third] = [[1, [2]], 4];
console.log(`first = ${first}`); // 1
console.log(`second = ${second}`); // 2
console.log(`third = ${third}`); // 4
// iterable
var iter = (function*(start) {
while (true) {
yield start++;
}
})(0);
var [v1, v2, v3, v4] = iter;
console.log(`v1 = ${v1}`); // 0
console.log(`v2 = ${v2}`); // 1
console.log(`v3 = ${v3}`); // 2
console.log(`v4 = ${v4}`); // 3
// 요소 스킵, 나머지 요소 캡처
var arr = [1, 2, 3, 4];
var [, sec, ...aRest] = arr;
console.log(`sec = ${sec}`); // 2
console.log(`aRest = ${aRest}`); // [3, 4]
"하드코딩" 스타일의 코드는 모두 없어지고, moreover 구조 분해 할당은 더욱 명확하고 직관적입니다 (좌우 대응)
삼.오브젝트 구조 분해 할당
var/let/const {key: varName, ...} = obj 구문은 오브젝트 구조 분해 할당을 나타냅니다
특별히 주의:할당 순서는 왼쪽에서 오른쪽으로 입니다. 실제 효과는:varName = obj[key] 입니다
분해되는 값은반드시 오브젝트로 강제 변환될 수 있어야 합니다. 따라서 undefined/null 을 구조 분해 할당하면 TypeError 가 보고됩니다
오브젝트 구조 분해 할당의 특징은 다음과 같습니다:
-
변수명과 오브젝트 속성명이 일치할 경우 간략화 가능
-
특정 속성명에 대해서만 할당 가능 (빈 자리를 남겨 스킵할 필요가 없습니다)
-
복잡한 중첩 (오브젝트 + 배열) 을 서포트
예를 들어:
// obj
var obj = {name: 'aae', age: 12, sex: 'F'};
// 특정 속성명에 대해서만 할당
var {name: mName, sex: mSex} = obj;
console.log(`mName = ${mName}`); // mName = aae
console.log(`mSex = ${mSex}`); // mSex = F
// 변수명과 속성명이相同할 경우 간략화
var {name, sex} = obj;
console.log(`name = ${name}`); // name = aae
console.log(`sex = ${sex}`); // sex = F
주의, 구조 분해 할당 왼쪽에 var/let/const 가 없는 경우 (즉 변수 선언을 잊었거나, 변수가 이미 있어 다시 선언하고 싶지 않은), 구문 오류가 발생합니다. 다음과 같습니다:
// var key;
{key} = {key: 'val'};
// 报错:Uncaught SyntaxError: Unexpected token =(…)
할당 기호 왼쪽의 {key} 는 블록 ({}) 으로 해석되기 때문입니다. 이 동작을 회피하는 방안은구조 분해 할당에 둥근 괄호를 추가 하는 것입니다. 예를 들어:
({key} = {key: 'val'});
console.log(`key = ${key}`); // key = val
둥근 괄호 안은 모두 식이며, {key} 는 실수로 블록으로 해석되지 않습니다
사.구조 분해 할당 동시에 기본값 설정
구문은 기본 파라미터 구문과 유사합니다. 예를 들어:
// default val
var [val = 'default val'] = [];
var {key: val = 'default val'} = {};
// 속성명이相同할 경우 간략화 가능
// FF43,45 都不支持,thinkjs,Chrome50 支持
// var {val = 'default val'} = {};
console.log(`val = ${val}`);
1 개의 문으로 기본값을 설정하고, 구조 분해 할당도 수행하지만, 구문은 더 복잡한 경우 구문이有些읽기 어렵습니다 (예를 들어 위의 var {key: val = 'default val'} = {};)
오.정리
이 특성도 금상첨화적인 것으로, "하드코딩" 스타일 코드를 감소하고, 그 가독성을 강화합니다
용도:
-
함수 정의 중의 오브젝트 파라미터, 예를 들어
function ajax(config),function ajax({url, data, callback})로 변경 후 API 가독성이 더욱 좋고, 기본값과配合하여 매우 편리합니다 (var attr = config.attr || defultVal;와 같은 조작을 회피) -
이터레이터와配合하여, map 을遍历하는 데 편리합니다 ([key, val] 遍历鍵値対、[key] 遍历鍵集、[, val] 遍历値集)
-
함수가 여러 개의 값을 반환하는 것을 구현 (배열을 반환하고, 반환 값을 받을 때 각 변수에 구조 분해 할당)
-
일부 CommonJS 모듈을インポート하고, 필요한 부분만 구조 분해 할당.ES6 모듈의 import 은 유사한 기능을 서포트
예를 들어:
// use
// 1
function ajax({url, data, callback}) {
console.log(`ajax(${url}, ${data}, ${callback})`);
}
ajax({url: 'www.xxx.xx', data: 'data'});
// log print: ajax(www.xxx.xx, data, undefined)
// 2
for (var [key, val] of new Map([['name', 'eea'], ['age', 12]])) {
console.log(`key = ${key}, val = ${val}`);
}
// log print: key = name, val = eea
// key = age, val = 12
// 3
var [res1, res2] = (function() {
return [1, {a: 1}];
})();
console.log(`res1 = ${res1}, res2 = ${res2}`);
// res1 = 1, res2 = [object Object]
참고 자료
- 《ES6 in Depth》:InfoQ 중국어 스테이션이 제공하는 무료 전자책
아직 댓글이 없습니다