
자바스크립트에서 배열은 참조 타입이기 때문에, 단순 할당으로는 새로운 복사본이 만들어지지 않는다.
const originArray = ['123', '456', '789'];
const newArray = originArray; // 참조만 복사됨
// 원본 배열 조작
originArray.push(10);
originArray.push(11);
originArray.push(12);
originArray.unshift(0);
console.log(originArray); // [0, '123', '456', '789', 10, 11, 12]
console.log(newArray); // [0, '123', '456', '789', 10, 11, 12]
// 😱 newArray도 같이 변경됨
// 방법 1: 전개 연산자 사용
const safeCopy1 = [...originArray];
// 방법 2: slice() 메서드 사용
const safeCopy2 = originArray.slice();
// 방법 3: Array.from() 사용
const safeCopy3 = Array.from(originArray);
originArray.push(13);
console.log(originArray); // [..., 13]
console.log(safeCopy1); // 원본 그대로 유지
const numbers = [1, 2, 3, 4, 5];
// ❌ 원본 배열을 변경하는 메서드들
numbers.push(6); // 원본 변경
numbers.pop(); // 원본 변경
numbers.unshift(0); // 원본 변경
numbers.shift(); // 원본 변경
numbers.splice(1, 1); // 원본 변경
// ✅ 새로운 배열을 반환하는 메서드들
const added = [...numbers, 6]; // 새 배열 반환
const filtered = numbers.filter(n => n > 3); // 새 배열 반환
const mapped = numbers.map(n => n * 2); // 새 배열 반환
const sliced = numbers.slice(1, 3); // 새 배열 반환
const concatenated = numbers.concat([6, 7]); // 새 배열 반환
const todos = [
{ id: 1, text: '자바스크립트 공부하기' },
{ id: 2, text: '리액트 공부하기' }
];
// ❌ 나쁜 예: 원본 배열 직접 수정
todos.push({ id: 3, text: '타입스크립트 공부하기' });
// ✅ 좋은 예: 새로운 배열 생성
const newTodos = [...todos, { id: 3, text: '타입스크립트 공부하기' }];
// ❌ 피해야 할 패턴
function addUser(users, newUser) {
users.push(newUser); // 원본 배열 변경
return users;
}
// ✅ 권장하는 패턴
function addUser(users, newUser) {
return [...users, newUser]; // 새로운 배열 반환
}
// 🚀 함수형 프로그래밍 스타일
const removeUser = (users, id) => users.filter(user => user.id !== id);
const updateUser = (users, id, updates) => users.map(user =>
user.id === id ? { ...user, ...updates } : user
);
배열을 다룰 때는 항상 "이 작업이 원본을 수정하는가?"를 생각해보자. 가능하면 항상 새로운 배열을 반환하는 메서드를 사용하거나, 명시적 배열을 복사한 후 작업하는 것이 안전하다.