>  기사  >  웹 프론트엔드  >  JavaScript_Basics ES6 버전의 구문 분석 할당

JavaScript_Basics ES6 버전의 구문 분석 할당

WBOY
WBOY원래의
2016-05-16 15:48:331281검색

구조분해 할당이란 무엇인가요?

구조 분해 할당을 사용하면 배열 또는 객체 리터럴과 유사한 구문을 사용하여 배열 및 객체 속성 값을 일련의 변수에 할당할 수 있습니다. 이 구문은 기존 속성 액세스보다 매우 간결하고 명확합니다.

구조 분해 할당을 사용하지 않고 배열의 처음 세 항목에 액세스:

var first = someArray[0];
var second = someArray[1];
var third = someArray[2];
 
var first = someArray[0];
var second = someArray[1];
var third = someArray[2];

구조 분해 할당을 사용하면 해당 코드가 더 간결해지고 읽기 쉬워집니다.

var [first, second, third] = someArray;
 
var [first, second, third] = someArray;

SpiderMonkey(Firefox의 JavaScript 엔진)는 이미 대부분의 구조 분해 할당 기능을 지원하지만 완전히 지원하지는 않습니다.
배열 및 반복 가능한 객체의 구조 분해 할당

위에서 배열 구조 분해 할당의 예를 보았습니다. 이 구문의 일반적인 형식은 다음과 같습니다.

[ variable1, variable2, ..., variableN ] = array;
 
[ variable1, variable2, ..., variableN ] = array;

이렇게 하면 배열의 해당 항목이 변수1부터 변수N까지 순차적으로 할당됩니다. 동시에 변수를 선언해야 하는 경우 구조 분해 표현식 앞에 var, let 또는 const 키워드를 추가할 수 있습니다.

var [ variable1, variable2, ..., variableN ] = array;
let [ variable1, variable2, ..., variableN ] = array;
const [ variable1, variable2, ..., variableN ] = array;
 
var [ variable1, variable2, ..., variableN ] = array;
let [ variable1, variable2, ..., variableN ] = array;
const [ variable1, variable2, ..., variableN ] = array;

사실 어떤 깊이에도 중첩할 수 있습니다.

var [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);
// 1
console.log(bar);
// 2
console.log(baz);
// 3
 
var [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);
// 1
console.log(bar);
// 2
console.log(baz);
// 3

또한 배열의 특정 항목을 건너뛸 수도 있습니다.

var [,,third] = ["foo", "bar", "baz"];
console.log(third);
// "baz"

 
var [,,third] = ["foo", "bar", "baz"];
console.log(third);
// "baz"

Rest 표현식을 사용하여 배열의 나머지 항목을 캡처할 수도 있습니다.

var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]
 
var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]

배열이 범위를 벗어나거나 배열에 존재하지 않는 항목에 액세스하는 경우 배열 인덱스를 통해 액세스하는 것과 동일한 값: 정의되지 않음을 얻게 됩니다.

console.log([][0]);
// undefined

var [missing] = [];
console.log(missing);
// undefined
 
console.log([][0]);
// undefined
 
var [missing] = [];
console.log(missing);
// undefined

배열 해체 및 할당 방법은 탐색 가능한 객체에도 적용됩니다.

function* fibs() {
 var a = 0;
 var b = 1;
 while (true) {
  yield a;
  [a, b] = [b, a + b];
 }
}

var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth);
// 5
 
function* fibs() {
 var a = 0;
 var b = 1;
 while (true) {
  yield a;
  [a, b] = [b, a + b];
 }
}
 
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth);
// 5

객체 분해 할당

객체 구조 분해 할당을 사용하면 변수를 객체의 다양한 속성 값에 바인딩할 수 있습니다. 바인딩할 속성의 이름을 지정하고 그 뒤에 바인딩할 변수를 지정하세요.

var robotA = { name: "Bender" };
var robotB = { name: "Flexo" };

var { name: nameA } = robotA;
var { name: nameB } = robotB;

console.log(nameA);
// "Bender"
console.log(nameB);
// "Flexo"
 
var robotA = { name: "Bender" };
var robotB = { name: "Flexo" };
 
var { name: nameA } = robotA;
var { name: nameB } = robotB;
 
console.log(nameA);
// "Bender"
console.log(nameB);
// "Flexo"

바인딩된 속성 이름이 속성 값을 받는 변수 이름과 동일한 경우 또 다른 구문 설탕이 있습니다.

var { foo, bar } = { foo: "lorem", bar: "ipsum" };
console.log(foo);
// "lorem"
console.log(bar);
// "ipsum"
 
var { foo, bar } = { foo: "lorem", bar: "ipsum" };
console.log(foo);
// "lorem"
console.log(bar);
// "ipsum"

배열과 마찬가지로 중첩될 수도 있습니다.

var complicatedObj = {
 arrayProp: [
  "Zapp",
  { second: "Brannigan" }
 ]
};

var { arrayProp: [first, { second }] } = complicatedObj;

console.log(first);
// "Zapp"
console.log(second);
// "Brannigan"
 
var complicatedObj = {
 arrayProp: [
  "Zapp",
  { second: "Brannigan" }
 ]
};
 
var { arrayProp: [first, { second }] } = complicatedObj;
 
console.log(first);
// "Zapp"
console.log(second);
// "Brannigan"

존재하지 않는 속성을 분해하면 정의되지 않은 상태가 됩니다.

var { missing } = {};
console.log(missing);
// undefined
 
var { missing } = {};
console.log(missing);
// undefined

객체의 구조 분해 할당을 사용할 때 또 다른 잠재적인 함정이 있습니다. 구조 분해 할당 중에 변수 선언(var, let 또는 const 키워드 없음)이 없다는 것입니다.

{ blowUp } = { blowUp: 10 };
// Syntax error
 
{ blowUp } = { blowUp: 10 };
// Syntax error

이는 JavaScript 구문이 엔진에 {로 시작하는 모든 명령문이 명령문 블록임을 알려주기 때문입니다(예: {console}은 법적 명령문 블록임). 해결 방법은 전체 명령문을 괄호 쌍으로 묶는 것입니다. 🎜>

({ safe } = {});
// No errors
 
({ safe } = {});
// No errors

기타 상황

null이나 정의되지 않은 구조를 해제하려고 하면 다음과 같은 유형 오류가 발생합니다.

var {blowUp} = null;
// TypeError: null has no properties
 
var {blowUp} = null;
// TypeError: null has no properties

그러나 다른 기본 유형(부울, 문자열 및 숫자)을 분해하면 정의되지 않은 상태가 됩니다.


var {wtf} = NaN;
console.log(wtf);
// undefined

 
var {wtf} = NaN;
console.log(wtf);
// undefined

결과가 놀라울 수도 있지만, 자세히 살펴보면 그 이유는 사실 매우 간단합니다. 객체 구조해제 및 할당을 수행할 때 구조해제된 객체는 Object로 강제 변환됩니다. null 및 정의되지 않은 경우를 제외하고 다른 유형은 객체로 강제 변환될 수 있습니다. 배열의 구조 할당을 수행할 때 구조 해제된 개체에는 순회자가 필요합니다.


기본값

존재하지 않는 속성에 대해 기본값을 지정할 수 있습니다.


var [missing = true] = [];
console.log(missing);
// true

var { message: msg = "Something went wrong" } = {};
console.log(msg);
// "Something went wrong"

var { x = 3 } = {};
console.log(x);
// 3
 
var [missing = true] = [];
console.log(missing);
// true
 
var { message: msg = "Something went wrong" } = {};
console.log(msg);
// "Something went wrong"
 
var { x = 3 } = {};
console.log(x);
// 3

실습 함수 매개변수

개발자로서 우리는 API 사용자에게 특정 순서로 일부 매개변수를 기억하도록 요구하기보다는 보다 유연한 API를 구현하기 위해 여러 속성이 포함된 객체를 함수 매개변수로 사용하는 경우가 많습니다. 매개변수가 사용될 때마다 속성 액세스를 피하기 위해 객체의 구조 분해 할당을 사용할 수 있습니다.


function removeBreakpoint({ url, line, column }) {
 // ...
}
 
function removeBreakpoint({ url, line, column }) {
 // ...
}

구성 개체

위의 예를 개선하기 위해 구조 해제할 객체 속성에 대한 기본값을 제공할 수 있습니다. 이는 많은 구성 항목이 합리적인 기본값을 갖기 때문에 구성 매개변수로 사용되는 객체에 매우 실용적입니다. 예를 들어 jQuery ajax 메소드의 두 번째 매개변수는 구성 객체이며 다음과 같이 구현할 수 있습니다.


jQuery.ajax = function (url, {
 async = true,
 beforeSend = noop,
 cache = true,
 complete = noop,
 crossDomain = false,
 global = true,
 // ... more config
}) {
 // ... do stuff
};
 
jQuery.ajax = function (url, {
 async = true,
 beforeSend = noop,
 cache = true,
 complete = noop,
 crossDomain = false,
 global = true,
 // ... more config
}) {
 // ... do stuff
};
이것은 다음과 같은 코드 중복을 방지합니다: var foo = config.foo ||


반복자와 함께 사용

Map 객체를 순회할 때 구조 분해 할당을 사용하여 [키, 값]을 순회할 수 있습니다.


var map = new Map();
map.set(window, "the global");
map.set(document, "the document");

for (var [key, value] of map) {
 console.log(key + " is " + value);
}
// "[object Window] is the global"
// "[object HTMLDocument] is the document"

 
var map = new Map();
map.set(window, "the global");
map.set(document, "the document");
 
for (var [key, value] of map) {
 console.log(key + " is " + value);
}
// "[object Window] is the global"
// "[object HTMLDocument] is the document"

횡단 키만 해당:


for (var [key] of map) {
 // ...
}

 
for (var [key] of map) {
 // ...
}

只遍历值:
for (var [,value] of map) {
 // ...
}

 
for (var [,value] of map) {
 // ...
}

여러 값 반환

배열을 반환하고 구조 분해 할당을 통해 반환 값을 추출합니다.


function returnMultipleValues() {
 return [1, 2];
}
var [foo, bar] = returnMultipleValues();

 
function returnMultipleValues() {
 return [1, 2];
}
var [foo, bar] = returnMultipleValues();

또는 키-값 쌍의 객체를 반환합니다.


function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var { foo, bar } = returnMultipleValues();

 
function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var { foo, bar } = returnMultipleValues();

둘 다 중간 변수를 사용하는 것보다 낫습니다.


function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var temp = returnMultipleValues();
var foo = temp.foo;
var bar = temp.bar;
 
function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var temp = returnMultipleValues();
var foo = temp.foo;
var bar = temp.bar;
계속 양식 사용:


function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

 
function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

导入 CommonJS 模块的指定部分

还没使用过 ES6 的模块吧,那至少使用过 CommonJS 吧。当导入一个 CommonJS 模块 X 时,模块提供的方法也许多余你实际使用的。使用解构赋值,你可以明确指定你需要使用模块的哪些部分:

const { SourceMapConsumer, SourceNode } = require("source-map");
 
const { SourceMapConsumer, SourceNode } = require("source-map");

如果你使用 ES6 的模块机制,你可以看到 import 声明时有一个类似的语法。
结论

我们看到,解构赋值在很多场景下都很实用。在 Mozilla,我们已经有很多经验。Lars Hansen 在 10 年前就向 Opera 引入了解构赋值,Brendan Eich 在稍微晚点也给 Firefox 添加了支持,最早出现在 Firefox 2 中。因此,解构赋值已经渗透到我们每天对 JS 的使用中,悄悄地使我们的代码更简短、整洁。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.