객체 — 속성·메서드·구조 분해
객체 리터럴 · 접근 · Object.keys/values/entries · 구조 분해 · spread.
객체는 JS 의 8번째 자료형이자 거의 모든 데이터의 형태입니다. JSON 응답·React props·설정·이벤트 객체 — 전부 객체. 10편은 객체를 만들고·읽고·합치고·꺼내는 모든 패턴을 한 번에 정리합니다.
객체 리터럴 — 기본형
const user = {
name: "준성",
age: 39,
active: true,
greet() { // 메서드 단축
return `Hi, ${this.name}`;
},
};
user.name; // "준성" — dot 접근
user["age"]; // 39 — bracket 접근 (동적 키)
user.greet(); // "Hi, 준성"
// 동적 키
const key = "name";
user[key]; // "준성"
// 계산된 키 (computed property name)
const prefix = "user_";
const obj = {
[prefix + "id"]: 1,
[`${prefix}name`]: "준성",
};
// { user_id: 1, user_name: "준성" }
단축 속성 — 같은 이름이면 한 번만
const name = "준성";
const age = 39;
// 길게
const user = { name: name, age: age };
// 단축 (ES6+) — 같은 이름이면 한 번만
const user = { name, age };
// 함수 반환에서 자주
function createUser(name, age) {
return { name, age, createdAt: Date.now() };
}
Object.keys · values · entries
const user = { name: "준성", age: 39, role: "admin" };
Object.keys(user); // ["name", "age", "role"]
Object.values(user); // ["준성", 39, "admin"]
Object.entries(user); // [["name","준성"], ["age",39], ["role","admin"]]
// for...of + entries 패턴 — 키와 값 같이 순회
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// entries → 객체 복원
Object.fromEntries([["a", 1], ["b", 2]]); // {a: 1, b: 2}
// 응용: 값만 변환
const upper = Object.fromEntries(
Object.entries(user).map(([k, v]) => [k, String(v).toUpperCase()])
);
구조 분해 할당 — 객체에서 값 꺼내기
const user = { name: "준성", age: 39, email: "[email protected]", role: "admin" };
// 기본
const { name, age } = user;
console.log(name, age); // "준성" 39
// 이름 바꾸기
const { name: userName, age: userAge } = user;
// 기본값
const { name, role = "user" } = user;
const { phone = "없음" } = user; // phone 키 없으면 기본값
// 나머지 모으기
const { name, ...others } = user;
// others = { age, email, role }
// 중첩 분해
const data = { profile: { city: "서울" } };
const { profile: { city } } = data;
구조 분해 + 함수 매개변수
// 매개변수 4개 넘으면 객체로 받고 분해
function createPost({ title, body, tags = [], publishAt = Date.now() }) {
return { title, body, tags, publishAt };
}
createPost({ title: "Hello", body: "World", tags: ["intro"] });
// publishAt 은 기본값
// tags 안 주면 [] (기본값)
// 호출 순서 자유
spread — 객체 복제와 합치기
// 얕은 복제
const copy = { ...user };
// 합치기 (뒤가 앞을 덮어씀)
const a = { x: 1, y: 2 };
const b = { y: 99, z: 3 };
const merged = { ...a, ...b }; // { x: 1, y: 99, z: 3 }
// 일부 덮어쓰기 — React state 업데이트 패턴
const updated = { ...user, age: 40 };
// Object.assign 도 같은 일 (mutate 주의)
Object.assign({}, a, b); // 새 객체로 합치기 (안전)
Object.assign(user, { age: 40 }); // user 자체 변경 ⚠️
spread 는 얕은 복제. 1단계만 복제됩니다. 내부 객체·배열은 같은 참조를 공유 — 그걸 바꾸면 원본에도 영향. 깊은 복제는 structuredClone(obj)(현대 API) 또는 JSON.parse(JSON.stringify(obj))(함수·undefined·Date 손실됨).
객체 비교 — 참조 vs 내용
const a = { x: 1 };
const b = { x: 1 };
const c = a;
a === b; // false ← 다른 객체 (참조 다름)
a === c; // true ← 같은 참조
// 내용 비교 (얕은)
function shallowEqual(a, b) {
const ka = Object.keys(a), kb = Object.keys(b);
if (ka.length !== kb.length) return false;
return ka.every(k => a[k] === b[k]);
}
// 깊은 비교는 lodash.isEqual 또는 직접 재귀
// node 22+ 라면 util.isDeepStrictEqual
객체 메서드 — 자주 쓰는 4개
| 메서드 | 용도 |
|---|---|
| Object.freeze(obj) | 속성 변경/추가 막기 (얕음) |
| Object.is(a, b) | === 와 거의 같지만 NaN/-0 처리 다름 |
| Object.hasOwn(obj, k) | 자기 자신 속성인지 (프로토타입 X) |
| Object.groupBy(arr, fn) | ES2024 — 배열을 객체로 그룹화 |
// in 연산자 vs hasOwn
"toString" in user; // true (프로토타입 체인 포함)
Object.hasOwn(user, "toString"); // false (자기 것만)
// freeze
const config = Object.freeze({ apiUrl: "https://..." });
config.apiUrl = "x"; // strict mode 에서 에러, 아니면 조용히 무시
실전 체크. ① 새 객체 만들 때는 { ...a, x: newVal } 패턴이 React/Redux 표준. ② API 응답 일부만 쓰려면 구조 분해 + 기본값. ③ 키-값 순회는 거의 항상 Object.entries + for...of. ④ 깊은 복제는 structuredClone.
11편 — 문자열 메서드
템플릿 리터럴, split·replace·slice, 정규식 살짝.
📚 쉽게 배우는 자바스크립트 교재
이전: 9편 배열 · 현재: 10편 (기초) · 다음 → 11편 문자열 · 진행: 10/26
이전: 9편 배열 · 현재: 10편 (기초) · 다음 → 11편 문자열 · 진행: 10/26