[JavaScript] ES6 - 구조 분해 할당 (feat. Spread/Rest 문법)

Letmegooutside·2022년 1월 2일
0

JavaScript

목록 보기
2/25
post-thumbnail

JavaScript destructuring

구조화된 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식

배열 구조 분해 할당

배열의 각 요소를 배열로부터 추출하여 변수리스트에 할당한다.
왼쪽의 변수리스트는 오른쪽 배열의 인덱스를 기준으로 할당된다.

사용법

const arr = [1,2,3];

// 배열의 인덱스를 기준으로 배열로부터 요소를 추출하여 변수에 할당한다.
// 변수 one, two, three가 선언되고 arr(initializer)이 비구조화(destructuring)되어 할당된다.
const [one, two, three] = arr;
console.log(one, two, three); // 1,2,3

// 디스트럭처링을 사용할 때에는 반드시 initializer를 할당해야 한다.
const[one, two, three]; // SyntaxError : Missing initializer in destructuring declaration

예시

let x,y,z;

[x,y] = [1,2]; 
console.log(x, y); //1 2

[x,y] = [1];
console.log(x,y); // 1 undefined

// 기본 값
[x,y,z=3] = [1,2];
console.log(x, y, z); // 1 2 3

// rest 문법
// 구조 분해 할당을 통해 원하는 값을 꺼내고, 나머지는 y에 들어간다.
[x, ...y] = [1,2,3];
console.log(x, y); // 1 [2,3]

// 아래와 같이 사용하면 오류 발생
[...x,y] = [1,2,3];

객체 구조 분해 할당

객체의 각 속성을 비구조화하여 변수에 할당하기 위해서는 프로퍼티 이름을 사용한다.
할당 연산자 왼쪽에는 객체 형태의 변수 리스트가 필요하다.

사용법

const obj = { 
	firtName: 'hey', 
	lastName: 'lee'
};

// 프로퍼티 키를 기준으로 구조 분해 할당이 이루어진다.(순서는 의미X)
// 변수 lastName, firstName이 선언되고, obj(initializer)가 비구조화되어 할당된다.
const { lastName, firstName } = obj;
console.log(lastName, firstName) // lee hey

예시

// 프로퍼티 키가 각각 prop1, prop2인 프로퍼티 값을 각각 변수 p1, p2에 할당
const { prop1: p1, prop2: p2 } = { prop1: 'a',prop2: 'b'};
console.log(p1, p2); // a b

// 아래는 위의 축약형이다.
const { prop1, prop2 } = { prop1: 'a',prop2: 'b'};
console.log(prop1, prop2); // a b

//default value
const { prop1, prop2, prop3 = 'c'} = { prop1: 'a',prop2: 'b'};
console.log(prop1, prop2, prop3) // a b c

//중첩 객체
const person = {
	name: 'Lee',
	address: {
		zipCode: '03724',
		city: 'Seoul'
	}
}
const { address : { city} } = person;
console.log(city) // Seoul


Spread / Rest 문법

ES6에서 도입된 문법으로 서로 완전히 다른 문법이지만 비슷한 부분이 있다.

Spread

객체 혹은 배열을 펼칠 수 있는 연산자이다. 기존의 것은 건들이지 않고 새로운 객체를 만들 때 사용한다.

// 객체
const a = { one: 1, two: 2};
const b = { ...a , three: 3};
cosole.log(b); // { one: 1, two: 2, three: 3}

// 배열
const a = [1, 2, 3];
const b = [...a, 999, ...a];
console.log(b); // [1, 2, 3, 999, 1, 2, 3]

✨ 자바스크립트 객체 복사

1. 참조할당

const original = { a:1, b:2 };

const copied = original;
original.a = 100;

console.log(copied === original) // true
console.log(copied.a); // 100

copied변수에 original변수 값 자체가 아닌 참조를 할당하여 original과 copied는 같은 객체를 바라보게 되므로 한 객체의 값을 수정하면, 다른 객체의 값 또 한 동일하게 변화한다.


2. Shallow Clone(얕은 복사)

객체의 참조값을 복사하여 새 객체를 생성한다.
복사된 객체의 프로퍼티는 원본 객체의 프로퍼티와 같은 메모리 주소를 참조한다.

  • Object.assign()
    첫번째 인자로 들어오는 객체에 두번째 인자로 들어오는 객체의 프로퍼티들을 복사한다.
const obj = { a: 1, b: 2 }
const target = { c: 3 }

const copiedObj = Object.assign(target, obj)

console.log(copiedObj) //{c: 3, a: 1, b: 2}

Object.assign()를 사용하면 복사하려는 객체 내부에 존재하는 개체는 완전한 복사가 이루어지지 않는다. 객체의 프로퍼티는 참조할당 된다.

const person = {
  age: 100,
  name: {
    first: "hy",
    last: "lee",
  },
}

const copied = Object.assign({}, person)

// 1depth의 수준에서만 복사가 이루어진다.
console.log(copied === person) // false
console.log(copied.name === person.name) //true

person.age = 1000
person.name.first = "paul"

console.log(copied.age) // 100
console.log(copied.name.first) // 'paul'

person의 프로퍼티 값을 변경하면, copied 객체의 프로퍼티 값도 변경된다.

  • Spread 연산자
    Object.assign()과 동일하다.
const person = {
  age: 100,
  name: {
    first: "hy",
    last: "lee",
  },
}
const copied = { ...person };

3. Deep Clone (깊은 복사)

객체의 실제 값을 복사하여 새 객체를 생성한다. 해당 객체와 프로퍼티까지 복사하는 방식으로 전부 복사하여 새 주소에 담기 때문에 참조를 공유하지 않는다.
Lodash의 deepClone() 함수 등을 사용하는 방법이 있다.

const original = {
  a: 1,
  b: {
    c: 2,
  },
}

const deepCopied = clonedeep(original)

console.log(original === copied); // false
console.log(original.b === copied.b); // false

original.a = 1000
original.b.c = 2000

console.log(deepCopied.a) // 1
console.log(deepCopied.b.c) // 2

(JS에서는 Number, String, Boolean 정도의 원시타입을 제외한 모든 객체는 메모리 주소에 대한 복사가 일어난다.)

Rest

구조 분해 할당 문법과 함께 사용하면 나머지(객체, 배열)를 rest에 담아서 추출할 수 있으며 함수의 매개변수에서 사용할 경우 정해지지 않은 수의 매개변수를 배열로 받을 수 있다.

rest는 객체, 배열, 함수의 매개변수에서 사용가능하며 객체와 배열에서 사용할 때는 구조 분해 할당 문법과 함께 사용된다.

// 객체
const a = {
  one: 1,
  two: 2,
  three: 3
}
const { three, ...rest } = a;
console.log(three); // 3
console.log(rest); // { one:1, two:2 }

// 배열
const a = [1, 2, 3];
const [ one, ...rest ] = a;
console.log(one); // 1
console.log(rest); // [2, 3]

// 매개변수
// 주로 매개변수의 갯수가 정해지지 않은 상황에서 사용한다.
function sum (...rest) {
	return rest;
}
const res1 = sum(1,2,3);
const res2 = sum(1,2);

// spread연산자를 사용하여 함수의 인자를 전달할 수 있다.
const a = [1,2,3];
console.log(sum(...a)); // [1,2,3]




Reference

https://hanamon.kr/javascript-spread-reat/
https://junwoo45.github.io/2019-09-23-deep_clone/

0개의 댓글