[JSTS-003][입문] 배열·객체를 원본 변경 없이 다루기 > IT 기술 공유

본문 바로가기

사이트 내 전체검색

뒤로가기 IT 기술 공유

[JSTS-003][입문] 배열·객체를 원본 변경 없이 다루기

페이지 정보

작성자 기술팀장 작성일 26-08-30 10:33 조회 249 댓글 0

본문

[이번 수업]

JavaScript 배열과 객체에 여러 값을 담는 방법을 익히고, 원본을 직접 바꾸지 않는 불변 데이터 처리의 이유를 배웁니다. map과 펼침 문법으로 새 값을 만들어 결과를 비교합니다.

[선수지식]

JSTS-001의 실행·기본문법과 JSTS-002의 타입·함수·스코프를 읽고 Node.js를 준비하세요.

[학습목표]

1. 배열과 객체의 쓰임을 구분한다.
2. 값 복사와 참조 공유의 차이를 설명한다.
3. 배열과 중첩 객체를 원본 변경 없이 갱신한다.

[핵심개념]

배열은 순서가 있는 값의 목록입니다. 대괄호로 만들고 0부터 시작하는 인덱스로 읽습니다.map은 각 항목에 함수를 적용한 새 배열을 만듭니다.

객체는 이름이 붙은 속성과 값을 묶습니다. 배열도 객체도 변수에 객체 자체가 복제되는 것이 아니라 그 객체를 가리키는 참조가 저장됩니다. const는 변수에 다른 값을 다시 대입하지 못하게 하지만 배열과 객체 내부 변경까지 막지는 않습니다.

불변 데이터 처리는 기존 배열·객체를 수정하는 대신 변경 내용을 반영한 새 값을 만드는 방식입니다. 바뀐 경로의 배열과 객체만 새로 만들고 바뀌지 않은 부분은 안전하게 재사용하는 구조적 공유를 사용할 수 있습니다.

배열 펼침 [...items]과 객체 펼침 { ...item }은 바깥 한 단계의 열거 가능한 속성을 복사합니다. 이것은 얕은 복사입니다. 중첩 객체까지 자동으로 새 객체가 되지 않으므로 profile.settings.theme을 바꾸려면 profile과 settings를 각각 펼쳐 새로 만들어야 합니다.

[따라하기]

immutable_demo.js에 다음을 저장하세요.

const original = [
  { id: 1, name: "A", active: false },
  { id: 2, name: "B", active: false },
];

const updated = original.map((item) =>
  item.id === 2 ? { ...item, active: true } : item,
);

const profile = { name: "민수", settings: { theme: "light" } };
const updatedProfile = {
  ...profile,
  settings: { ...profile.settings, theme: "dark" },
};

console.log("same_array", original === updated);
console.log("original_second", original[1].active);
console.log("updated_second", updated[1].active);
console.log("themes", profile.settings.theme, updatedProfile.settings.theme);
console.log("shared_first", original[0] === updated[0]);

Windows·macOS·Linux 모두 터미널에서 node immutable_demo.js로 실행합니다. 예상 결과는 다음과 같습니다.

same_array false
original_second false
updated_second true
themes light dark
shared_first true

updated는 original과 다른 배열입니다. id가 2인 객체만 펼침 문법으로 새로 만들었으므로 원본의 active는 false로 남습니다.

[흔한 실수]

첫째, const가 객체 내부도 불변으로 만든다고 생각합니다. 둘째, copy = original을 복사라고 생각합니다. 셋째, 객체 펼침 한 번이면 중첩 객체까지 모두 복사된다고 믿습니다.

[보안 주의]

불변 업데이트는 입력 검증이나 권한 검사를 대신하지 않습니다. 외부 객체를 합칠 때 허용할 키만 골라 새 객체를 만들고 __proto__·constructor·prototype 같은 위험한 키를 데이터 경로로 사용하지 마세요. JSON 크기와 중첩 깊이를 제한하고 예상한 배열·객체 구조와 값 범위를 검사합니다.

[직접 해볼 과제]

상품 배열 [{ id: 1, stock: 2 }, { id: 2, stock: 5 }]를 만드세요. map과 펼침 문법으로 id 1의 stock만 3으로 바꾼 새 배열을 만들고, 원본 stock은 2인지 확인하세요. 이어 없는 id를 받았을 때 모든 기존 객체를 그대로 재사용하는지도 ===로 검사합니다.

[확인문제]

1. const로 선언한 배열도 push로 바뀔 수 있는 이유는 무엇인가요?
2. 객체 펼침이 얕은 복사라는 말은 무슨 뜻인가요?
3. 예제에서 original[0]과 updated[0]이 같은 객체인 이유는 무엇인가요?

[다음 학습]

다음 글은 WEB-003 반응형 화면과 모바일 우선 설계입니다. JSTS 트랙에서는 JSTS-004 이벤트 루프와 비동기 처리로 이어집니다.

[공식 참고 자료]

ECMAScript Array.prototype.map 규격
https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.map

ECMAScript 객체 초기화·펼침 규격
https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-object-initializer

ECMAScript Object.freeze 규격
https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.freeze

Node.js 명령줄 실행 문서
https://nodejs.org/api/cli.html#node-options-script-arguments

OWASP 프로토타입 오염 방지 지침
https://cheatsheetseries.owasp.org/cheatsheets/Prototype_Pollution_Prevention_Cheat_Sheet.html

댓글목록 0

등록된 댓글이 없습니다.

Copyright © 소유하신 도메인. All rights reserved.

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

PC 버전으로 보기