구조분해할당
// 1. 배열의 구조 분해 할당
let arr = [1, 2, 3];
let [one, two, three, four = 4] = arr;
// 2. 객체의 구조 분해 할당
let person = {
name: "박진주",
age: 23,
hobby: "요가",
};
let { age: myAge, name, hobby, extra = "hello" } = person;
console.log(name, myAge);
// 3. 객체 구조 분해 할당을 이용해서 함수의 매개변수를 받는 방법
const func = ({ name, age, hobby, extra }) => {
console.log(name, age, hobby, extra);
};
func(person);
배열과 객체는 일일이 인덱스나 점 표기법을 사용해서 변수 할당하지 않아도 된다. 구조 분해 할당으로 간단하게 할당할 수 있다.
- 배열 : let [ 사용할 변수명 ] = 배열
- 객체 : let { 프로퍼티 } = 객체
이때 자료 구조에 들어있지 않은 새로운 변수를 만들 수도 있다. 그리고 배열의 구조 분해 할당은 인덱스 순서대로 할당되고, 객체의 경우는 프로퍼티 이름과 매칭되므로 순서와는 관련이 없다. 할당받는 변수의 이름을 바꾸고 싶다면 age: myAge 와 같이 ' : '을 이용하여 명시하면 된다.
Spread 연산자와 Rest 매개변수
// 1. Spread 연산자
// -> Spread : 흩뿌리다, 펼치다 라는 뜻
// -> 객체나 배열에 저장된 여러개의 값을 개별로 흩뿌려주는 역할
let arr1 = [1, 2, 3];
let arr2 = [4, ...arr1, 5, 6];
let obj1 = {
a: 1,
b: 2,
};
let obj2 = {
...obj1,
c: 3,
d: 4,
};
function funcA(p1, p2, p3) {
console.log(p1, p2, p3);
}
funcA(...arr1);
// 2. Rest 매개변수
// -> Rest는 나머지 , 나머지 매개변수
function funcB(one, two, ...rest) {
console.log(rest);
}
funcB(...arr1);
Spread 연산자는 객체나 배열에 저장된 여러개의 값을 흩뿌린다. 배열 내에 배열 값을 순서대로 넣거나, 객체 내에 객체 프로퍼티 값을 순서대로 넣거나.
Rest 매개변수는 매개변수 자리에서 쓰이며, 앞 쪽에서 남은 나머지 매개변수를 배열로 한꺼번에 받는 역할을 한다. 그래서 매개변수의 맨 마지막 자리 또는 단독으로만 쓰일 수 있으며, ' ... ' 뒤의 이름은 무엇이든 상관없다.
Spread 연산자와 Rest 매개변수는 사용법은 같지만 쓰이는 위치, 기능이 서로 다름을 유의하자.
원시타입 VS 객체타입
let a1 = 1;
let a2 = a1;
a2 = 3;
console.log(a1); // 1
let b1 = { name: "박진주" };
let b2 = b1;
b2.name = "김진주";
console.log(b1); // 김진주
b1.name = "박진주";
let b3 = { ...b1 };
b3.name = "이진주";
console.log(b1); // 박진주
- 원시타입 : Number, String, Boolean, Null, Undefined
- 객체타입 : Object - Array, Function, RegexExp
원시타입은 값 자체로써 변수에 저장되고 복사된다. 값을 복사할 때, a1이 가리키는 메모리의 1이란 값은 변하지 않고 새로운 메모리 공간에 1을 할당하고 a2가 이를 가리킨다. 이것은 변수의 값을 수정할 때에도 마찬가지이다. a2=3이 되면 새로운 메모리 공간에 3을 할당한다. 이처럼 원시타입은 메모리 값이 바뀌지 않기 때문에, 불변값이라고 한다. 이를 통해 알 수 있듯 원본이 수정될 일이 없는 '깊은 복사'가 이루어진다.
그러나 객체타입은 참조값을 통하여 변수에 저장되고 복사된다. 그래서 b2에 b1을 복사하면 변수는 같은 참조값을 가리키기 때문에 원본의 값이 함부로 수정될 수가 있다. 이렇게 객체타입은 메모리 값이 바뀔 수 있으므로 가변값이다. 그래서 새로운 객체를 생성하고, 복사할 객체의 프로퍼티만 spread 연산자로 복사하는 방법이 있다.
하지만! 여기서 주의해야할 점은 spread 연산자는 깊은 복사를 하지 않는다는 것이다. spread 연산자는 객체의 최상위 레벨만 깊은 복사가 이루어져서, 객체 내부의 원시타입은 깊은 복사가 되지만, 객체 내부의 객체타입은 여전히 참조를 공유하는 얕은 복사이다. 자바스크립트에서 객체타입의 깊은 복사를 하려면 JSON이나 라이브러리를 사용해야 한다.
++ 객체간 비교(===, !==)도 참조값을 기준으로 이루어진다.
반복문으로 배열과 객체 순회하기
// 1. 배열 순회
let arr = [1, 2, 3];
// 1.1 배열 인덱스
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 1.2 for of 반복문
for (let item of arr) {
console.log(item);
}
// 2. 객체 순회
let person = {
name: "박진주",
age: 23,
hobby: "요가",
};
// 2.1 Object.keys 사용
// -> 객체에서 key 값들만 뽑아서 새로운 배열로 반환
let keys = Object.keys(person);
for (let key of keys) {
const value = person[key];
console.log(key, value);
}
// 2.2 Object.values
// -> 객체에서 value 값들만 뽑아서 새로운 배열로 반환
let values = Object.values(person);
for (let value of values) {
console.log(value);
}
// 2.3 for in
for (let key in person) {
const value = person[key];
console.log(key, value);
}
- 배열 원소 순회 : for of
- 객체 key값 순회 : for in
- 객체에서 key값들을 뽑아 배열로 반환 : Object.keys(객체)
- 객체에서 value값들을 뽑아 배열로 반환 : Object.values(객체)
우리는 지난 시간, 객체에 특정 프로퍼티가 존재하는지 확인할 때 in 연산자를 사용했다. 그러므로 객체 순회는 for in 을 사용한다고 쉽게 기억하자.
'프론트엔드 > 한 입 크기로 잘라먹는 리액트' 카테고리의 다른 글
| JavaScript - 동기와 비동기, 비동기 작업 처리하기(콜백함수, Promise, Async&Await) (1) | 2025.01.17 |
|---|---|
| JavaScript - 배열메서드(요소 조작, 순회와 탐색, 배열 변형), Date 객체와 날짜 (2) | 2025.01.17 |
| JavaScript - 객체, 배열, Truthy와 Falsy, 단락 평가 (0) | 2025.01.13 |
| JavaScript - 반복문, 함수, 함수 표현식과 화살표 함수, 스코프 (0) | 2025.01.13 |
| JavaScript - 형 변환, 연산자, 조건문 (0) | 2025.01.10 |