reduce
배열을 단일 값으로 줄이는 메서드
합계
const grades = [1, 2, 3];
const sum = grades.reduce((total, current) => {
return total + current;
}, 0);
total, current 2개의 매개변수를 사용합니다.
total은 reduce가 항상 마지막으로 계산한 값을 참조합니다.
current는 지금 처리할 항목입니다.
0을 넣는 이유
- 첫 번째 루프에서 total 변수에 할당될 값을 정의하는 것입니다.
- 빈 배열을 대상으로 할 경우 초기값이 없으면 TypeError가 발생됩니다.
- 초기값 없이 첫 번째 요소부터 시작하면, 첫 번째 요소가 누락되거나 불필요한 조건 검사를 추가해야 할 수도 있습니다.
곱셈
const numbers = [1, 2, 3];
const result = numbers.reduce((total, current) => {
return total * current;
}, 1);
곱셉을 할 때는 시작 값을 1로 지정합니다.
초기값이 0이면 곱하는 값이 0이 되어 버리기 때문입니다.
객체 키/값 접근, 복사, 병합
접근
- 점 표기
const user = {
id: 1,
firstName: "Jane",
lastName: "Kwon",
age: 35
};
user.firstName = "Lily";
user.age = user.age + 1;
console.log(user); // {id: 1, firstName: "Jane", lastName: "Kwon", age: 36}
function getPhoneNumber(user) {
return `${user.name}'s phone number is ${user.phone}.`
}
console.log(getPhoneNumber({user: "Jane", phone: "010-1111-2222"}));
// "Jane's phone number is 010-1111-2222."
console.log(getPhoneNumber({user: "Lily", phone: "010-3333-4444"}));
// "Lily's phone number is 010-3333-4444."
const로 정의된 객체의 속성 값을 업데이트할 수 있다고 해서 변수가 상수라는 의미는 아니며 단지 재할당할 수 없다는 의미입니다.
따라서 변수는 항상 객체이지만, 그 내용(속성)은 변경될 수 있습니다.
const user = {
id: 1,
firstName: "Sam",
lastName: "Doe",
age: 20
};
user.lastName = "Blue";
user.age = user.age + 1;
console.log(user); // {id: 1, firstName: "Sam", lastName: "Blue", age: 21}
- Object.keys()
const user = { name: 'Jane', age: 35, gender: 'female' };
const keys = Object.keys(user);
console.log(keys); // [ 'name', 'age', 'gender' ]
- Object.values()
const values = Object.values(user);
console.log(values); // [ 'Jane', 35, 'female' ]
- Object.entries()
const entries = Object.entries(user);
console.log(entries); // [ [ 'name', 'Jane' ], [ 'age', 35 ], [ 'gender', 'female' ] ]
복사
얕은 복사
- 객체의 첫 번째 수준에 있는 값만 복사하는 방식
- 복사본과 원본이 같은 참조를 공유하게 됨
- 복사본을 변경하면 원본도 함께 변경됨
깊은 복사
- 객체 내부의 모든 값을 완전히 복사하여 새로운 메모리 공간에 할당하는 방식
- 객체의 실제 값 자체를 복사함
- 참조가 완전히 끊어진 독립적인 객체 생성
- 복사본을 변경해도 원본에 영향을 주지 않음
- 할당 연산자(=)
복사된 객체를 변경하면 원본 객체도 변경됩니다.
let original = { a: 1 };
let copy = original;
copy.a = 2;
console.log(original.a); // 2
- Object.assign()
얕은 복사를 할 수 있습니다. 객체 내부의 객체나 배열은 참조만 복사됩니다.
let original = { a: 1, b: { c: 2 } };
let copy = Object.assign({}, original);
copy.b.c = 3;
console.log(original.b.c); // 3
- 스프레드 연산자( {...} )
얕은 복사를 할 수 있습니다.
let original = { a: 1, b: { c: 2 } };
let copy = { ...original };
copy.b.c = 3;
console.log(original.b.c); // 3
- JSON 직렬화 및 역직렬화
깊은 복사를 할 수 있습니다. 하지만 함수나 undefined, Symbole 등을 처리할 수 없습니다.
let original = { a: 1, b: { c: 2 } };
let copy = JSON.parse(JSON.stringify(original));
copy.b.c = 3;
console.log(original.b.c); // 2
- 깊은 복사 라이브러리
lodash와 같은 라이브러리를 사용하면 더 복잡한 객체의 깊은 복사를 쉽게 할 수 있습니다.
const _ = require('lodash');
let original = { a: 1, b: { c: 2 } };
let copy = _.cloneDeep(original);
copy.b.c = 3;
console.log(original.b.c); // 2
- 수동 깊은 복사
재귀 함수를 사용하여 수동으로 깊은 복사를 구현할 수도 있습니다.
function deepCopy(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
let original = { a: 1, b: { c: 2 } };
let copy = deepCopy(original);
copy.b.c = 3;
console.log(original.b.c); // 2
병합
- Object.assign()
중첩된 객체는 덮어쓰기가 되는 얕은 병합을 할 수 있습니다.
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { b: { d: 3 }, e: 4 };
let merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: { d: 3 }, e: 4 }
- 스프레드 연산자( {...} )
얕은 병합을 할 수 있습니다.
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { b: { d: 3 }, e: 4 };
let merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: { d: 3 }, e: 4 }
- 수동 깊은 병합
재귀 함수를 사용하여 중찹된 객체를 병합해야 합니다.
function deepMerge(target, source) {
for (const key in source) {
if (source[key] instanceof Object && key in target) {
Object.assign(source[key], deepMerge(target[key], source[key]));
}
target[key] = source[key];
}
return target;
}
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { b: { d: 3 }, e: 4 };
let merged = deepMerge({}, obj1);
deepMerge(merged, obj2);
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
- lodash의 merge()
깊은 병합
const _ = require('lodash');
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { b: { d: 3 }, e: 4 };
let merged = _.merge({}, obj1, obj2);
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
- ramda의 mergeDeepRight()
깊은 병합
const R = require('ramda');
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { b: { d: 3 }, e: 4 };
let merged = R.mergeDeepRight(obj1, obj2);
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }'Javascript' 카테고리의 다른 글
| 자바스크립트 공부6 - JS 모듈 시스템, 조건문과 삼항 연산자 (1) | 2025.06.25 |
|---|---|
| 자바스크립트 공부5 - this와 화살표 함수의 관계 (2) | 2025.06.02 |
| 자바스크립트 공부4 - 비동기 처리 (1) | 2025.05.29 |
| 자바스크립트 공부2 - 함수 (1) | 2025.05.16 |
| 자바스크립트 공부1 - ES6 문법 정리 (1) | 2025.05.15 |