본문으로 건너뛰기

실행 컨텍스트와 불변 객체

· 약 3분
준열
프론트엔드 개발자

코어 자바스크립트 스터디 2주차 내용을 정리했습니다. 이번 주제는 실행 컨텍스트불변 객체입니다.

🔒 불변 객체 (Immutable Object)

불변 객체는 내부 상태가 변하지 않는 객체를 의미합니다. 프로그래밍에서는 특히 함수형 프로그래밍, 라이브러리/프레임워크, 디자인 패턴 등에서 불변 객체 개념이 자주 등장합니다.

불변성의 중요성

  • 기본형 데이터는 값을 변경할 수 없습니다
  • 참조형 데이터도 프로퍼티를 바꾸지 않으면 변경된 것이 아닙니다
  • 어떤 함수를 통해 객체를 전달받고 변경을 하더라도, 원본 객체는 절대로 변경되지 않아야 할 때가 많습니다

⚠️ 가변성으로 인한 문제

// 객체의 가변성에 따른 문제
var user = {
name: "Jaenam",
gender: "male",
};

var changeName = function (user, newName) {
var newUser = user;
newUser.name = newName;
return newUser;
};

var user2 = changeName(user, "Jung");
console.log(user.name, user2.name); // Jung Jung
console.log(user === user2); // true (같은 객체)

문제점: user2가 바뀌면 user도 바뀜 → 두 객체는 같은 참조값을 가지므로 불변성이 깨짐

✅ 해결책: 새로운 객체 생성

// 새로운 객체를 만들어 반환
var changeName = function (user, newName) {
return {
name: newName,
gender: user.gender,
};
};

var user2 = changeName(user, "Jung");
console.log(user.name, user2.name); // Jaenam Jung
console.log(user === user2); // false

한계: 하지만 이 방식은 객체가 커질수록 하드코딩해야 할 코드가 많아짐 → 비효율적

📋 복사 방식의 구분

복사 방식설명
얕은 복사 (Shallow Copy)1단계 값만 복사. 중첩 객체는 주소(참조)만 복사됨
깊은 복사 (Deep Copy)중첩된 내부 값까지 전부 재귀적으로 복사

🔄 얕은 복사 (Shallow Copy)

var copyObject = function (target) {
var result = {};
for (var prop in target) {
result[prop] = target[prop];
}
return result;
};

주의사항: 얕은 복사는 참조형 데이터(객체, 배열 등)의 경우 동일한 메모리 주소를 참조하므로, 내부 프로퍼티가 바뀌면 원본도 영향 받음

🕳️ 깊은 복사 (Deep Copy)

재귀적 깊은 복사

var copyObjectDeep = function (target) {
var result = {};
if (typeof target === "object" && target !== null) {
for (var prop in target) {
result[prop] = copyObjectDeep(target[prop]); // 재귀
}
} else {
result = target;
}
return result;
};

주의사항:

  • typeof null === 'object'이기 때문에, null은 따로 필터링 필요
  • hasOwnProperty를 활용하면 프로토타입에서 상속된 프로퍼티는 제외 가능

ES6+ 고급 복사

// ES6 이상에서 getter/setter까지 복사하려면
Object.getOwnPropertyDescriptor(obj, prop);
Object.getOwnPropertyDescriptors(obj);

JSON을 이용한 간단한 깊은 복사

const deepCopied = JSON.parse(JSON.stringify(obj));

한계: undefined, 함수, Symbol, __proto__ 등은 복사되지 않음

🤷 undefined vs null

자바스크립트에서 "없음"을 표현하는 두 가지 방법:

설명
undefined자바스크립트가 자동으로 부여하거나, 명시적으로 지정 가능
null개발자가 명시적으로 설정하는 '값이 없음'

undefined가 자동으로 부여되는 경우

let x;
console.log(x); // undefined

const obj = {};
console.log(obj.name); // undefined

function noReturn() {}
console.log(noReturn()); // undefined

배열에서의 undefined vs 빈 요소

const arr1 = [1, undefined, 3];
const arr2 = [1, , 3];

arr1.forEach((v, i) => console.log(i, v));
// 0 1
// 1 undefined
// 2 3

arr2.forEach((v, i) => console.log(i, v));
// 0 1
// 2 3 → index 1은 순회되지 않음

핵심:

  • 명시적 undefined는 실존
  • 비어있는 요소는 순회 대상 아님

📝 undefined vs null 사용 지침

  • undefined: 엔진이 자동으로 줄 수 있으며, 존재하지 않는 값을 의미
  • null: 개발자가 의도적으로 비워두는 값

권장사항

의도적으로 값이 없음을 표현할 때는 null을 사용하고, undefined는 값이 할당되지 않은 상태로 두는 것이 좋습니다.

🎯 정리

  • 불변 객체는 원본을 보호하기 위해 새로운 객체를 생성하는 패턴
  • 얕은 복사는 1단계만, 깊은 복사는 중첩된 모든 레벨을 복사
  • JSON 방식은 간단하지만 제약사항이 있음
  • undefined는 자동 할당, null은 개발자 의도
  • 빈 배열 요소와 undefined는 forEach에서 다르게 동작

스터디: 코어 자바스크립트 2주차