javascript

ES6. 구조 분해 할당

Bittersweet- 2022. 2. 7. 15:57
728x90

객체와 배열을 변수로 '분해'할 수 있게 해주는 것을 구조 분해 할당(destructuring assignment)이라고 할 수 있다. 이 외에도 함수의 매개변수가 많거나 매개변수의 기본값 설정이 필요한 경우에도 구조 분해 할당을 활용할 수 있다.

 

var x = [1, 2, 3, 4, 5];
var [y, z] = x; // 구조 분해 할당을 이용해 y는 x[0], z는 z[1]을 할당함.

console.log(y); // 1
console.log(z); // 2

이제 인덱스를 이용해 배열에 접근하지 않고도 변수로 배열의 값을 사용할 수 있게 되었다. 아래의 예시처럼 split같은 반환값이 배열인 메서드와 함께 활용해도 좋다.

let arr = ["Bora", "Lee"];
let [firstName, lastName] = arr;

console.log(firstName); // Bora;
console.log(lastName); // Lee;

let [firstName, lastName] = "Bora Lee".split(''); // Array [B, o]

* 구조 분해 할당은 Perl이나 Python 등 다른 언어가 가지고 있는 기능이다.

 

let a, b, rest;
[a, b] = [10, 20];

console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];

console.log(rest); // Array [30, 40, 50]

 

[ 배열 구조 분해 ]

 

기본 변수 할당

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

var [red, yellow, green] = foo;

console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "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

 

변수 값 교환하기

하나의 구조 분해 표현식만으로 두 변수의 값을 교환할 수 있다.

구조 분해 할당 없이 두 값을 교환하려면 임시 변수가 필요하다.

var a =1;
var b =3;

[a, b] = [b, a]

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

 

함수가 반환한 배열 분석

함수는 이전부터 배열을 반환할 수 있었으며 구조 분해를 사용하면 반환된 배열에 대한 작업을 더 간결하게 수행할 수 있다.

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();

 

변수에 배열의 나머지를 할당하기

배열을 구조 분해할 경우, 나머지 구문을 이용해 분해하고 남은 부분을 하나의 변수에 할당할 수 있다.

var [a, ...b] = [1, 2, 3];

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

* 나머지 요소의 오른쪽 뒤에 쉼표가 있으면 syntax Error가 발생함.

var [a, ...b,] = [1, 2, 3];

 

[ 객체 구조 분해 ]

 

기본 할당

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});

😵‍💫  참고

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

{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

 

기본값 갖는 새로운 이름의 변수에 할당하기

새로운 변수명 할당과 기본값 할당을 한번에 할 수 있다.

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

console.log(aa); // 3
console.log(bb); // 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
});

ES2015

function drawES2015Chart({size = 'big', cords = {x:0, y:0}, radius = 25} = {}) {
  console.log(size, cords, radius);
}

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

drawES2015Chart 함수의 원형에서 구조 분해된 좌변에 빈 오브젝트 리터럴을 할당하는 것을 볼 수 있다.

{size = 'big', cords = {x:0, y:0}, radius = 25} = {}.

빈 오브젝트를 우변에 할당하지 않고도 함수를 작성할 수 있다. 하지만 지금의 형태에서 단순히 drawES2015Chart()와 같이 어떤 매개변수 없이도 호출할 수 있지만, 우변의 빈 오브젝트 할당을 없앤다면 함수 호출시 적어도 하나의 인자가 제공되어야 한다. 이 함수가 어떠한 매개 변수 없이도 호출할 수 있길 원한다면 지금 형태가 유용하고, 무조건 객체를 넘기길 원하는 경우에는 빈 객체 할당을 하지 않는 것이 유용할 수 있다.

 

중첩된 객체 및 배열의 구조 분해

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"

 

함수 매개변수로 전달된 객체에서 필드 해체하기

user 객체로부터 id, displayName 및 fistName을 해체해 출력

function userId({id}) {
  return id;
}

function whois({displayName: displayName, fullName: {fistName: 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"

 

계산된 속성 이름과 구조 분해

계산된 속성 이름(computed property name)은, 객체 리터럴과 비슷하게 구조 분해에도 사용될 수 있다.

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

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

 

객체 구조 분해에서 Rest

rest 속성은 구조 분해 패턴으로 걸러지지 않은 열거형 속성의 키를 가진 나머지 항목들을 모은다.

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // {c: 30, d: 40}

 

속성 이름이 유효한 JavaScript 식별자명이 아닌 경우

구조 분해는 JavaScript 식별자 이름으로 적합하지 않은 속성명이 제공된 경우에도 이용할 수 있다. 이때는 대체할 유효한 식별자명을 제공해야 한다.

const foo = {'fizz-buzz': true};
const {'fizz-buss': fizzBuss} = foo;

console.log(fizzBuss); // "true"

'javascript' 카테고리의 다른 글

아코디언 메뉴  (0) 2022.02.17
페이지 전환 효과  (0) 2022.02.17
String.prototype.trim()  (0) 2022.01.13
object.assign(target, sources)  (0) 2022.01.11
페이지 라이프 사이클 -DOMContentLoaded, load, unload  (0) 2022.01.11