Object 한 줄 요약
Object는 "이름 붙은 값(키-값)"을 묶어 두는 기본 데이터 구조다.
서버 응답/설정값/유저 정보처럼 "데이터 레코드"를 표현할 때 제일 많이 쓴다.
처음 보면 Map이랑 뭐가 다르지? 싶을 수 있다.
하지만 Object는 아래 같은 데이터를 표현할 때 거의 기본으로 등장한다.
- 서버 응답 데이터(JSON)
- 설정값(config)
- 유저 정보
그런데 막상 정리해서 설명하려고 하면
- “프로퍼티? 키? 필드? 뭐가 뭔데?”
- “for...in이랑 for...of는 또 뭐가 다른데?”
- “Map이랑은 언제 뭐 써야 돼?”
여기서 헷갈리기 쉽다.
이번 글은 Object 리터럴({}) 기준으로 기본기를 정리하고,
중간에 Map과도 가볍게 비교하는 흐름으로 간다.
먼저 감 잡기 (Map과 차이)
- Object: 데이터 레코드/모델/설정값에 강함, JSON 친화적
- Map: 키-값 컬렉션(테이블/캐시)에 강함, 동적 추가/삭제/검색이 잦을 때 유리
어떤 걸 쓰면 좋냐는 보통 이렇게 갈린다.
- 서버 응답 / 설정 / 도메인 모델 중심이면 → Object
- 키가 동적으로 늘었다 줄었다 / 캐시처럼 쓰고 싶다면 → Map
용어 10초 정리
블로그/문서에서 아래 단어가 자주 나오는데, 처음엔 이렇게 이해하면 충분하다.
- 컬렉션(Collection): 값을 여러 개 담아두는 자료형/자료구조 (예: Array, Set, Map, Object)
- 이터러블(Iterable): for...of로 순회할 수 있는 값 (예: Array, Set, Map, 문자열)
- 프로퍼티(Property): Object에 붙은 key: value 한 쌍
- 키(Key): 프로퍼티 이름 (대부분 문자열)
여기서 포인트 하나:
- Object는 컬렉션처럼 값 여러 개를 담지만, 기본적으로 이터러블이 아니다.
- 그래서 for...of로 바로 못 돌고, Object.keys/values/entries로 뽑아서 돈다.
언제 Object를 쓰면 좋은가?
아래 상황이면 Object를 먼저 떠올리면 된다.
- 서버랑 JSON으로 주고받는 데이터일 때
- “이름 붙은 값 몇 개”를 묶는 레코드/모델/설정값일 때
- 키가 전부 문자열(식별자) 형태이고, 구조가 비교적 정적일 때
반대로 이런 느낌이면 Map도 같이 고려해보자.
- 키가 동적으로 늘었다 줄었다 한다
- 추가/삭제/검색이 잦고, “테이블/캐시”처럼 굴리고 싶다
실무에서 가장 많이 쓰는 1줄 (얕은 복사 + 불변 업데이트)
const nextUser = { ...user, name: '시니어 지망생' };
{ ...user }→ 얕은 복사(shallow copy)- 뒤에 덮어쓴 프로퍼티만 바뀐다
이 한 줄은 상태 업데이트(특히 프론트)에서 정말 자주 나온다.
핵심 문법/메서드 5개만 먼저 보기
obj.key/obj['key']: 프로퍼티 접근delete obj.key: 프로퍼티 삭제'key' in obj: 키 존재 여부(프로토타입 체인 포함)Object.keys(obj): 키 배열Object.entries(obj):[key, value]쌍 배열
const user = { id: 1, name: '주니어', role: 'dev' };
console.log(user.name); // '주니어'
console.log(user['role']); // 'dev'
console.log('id' in user); // true
console.log(Object.keys(user));
// ['id', 'name', 'role']
delete user.role;
console.log(user);
// { id: 1, name: '주니어' }
Object가 뭐냐?
한 줄로 정리하면
"이름이 붙은 값들을 묶어 놓은 데이터 구조"
조금만 더 풀면
- 키(프로퍼티 이름) → 문자열 또는 심벌
- 값(value) → 어떤 타입이든 가능 (숫자, 문자열, 배열, 객체, 함수 등)
- 점(
.) 또는 대괄호([])로 접근
const user = {
id: 1,
name: '주니어',
role: 'dev',
};
console.log(user.id); // 1
console.log(user.name); // '주니어'
console.log(user['role']); // 'dev'
여기서 user는 Object 리터럴로 만든 객체다.
{ ... }안에key: value형태로 프로퍼티들을 정의한다- 키는 보통 문자열로 작성하되, 따옴표는 생략 가능 (
name,role등)
프로퍼티 다루기: 추가 / 수정 / 삭제
Object는 만들어진 뒤에도 자유롭게 프로퍼티를 추가/수정/삭제 할 수 있다.
추가 & 수정
const user = { id: 1 };
user.name = '주니어'; // 추가
user['role'] = 'dev'; // 추가 (대괄호 문법)
user.name = '시니어 지망생'; // 수정
console.log(user);
// { id: 1, name: '시니어 지망생', role: 'dev' }
점 표기법(obj.key)과 대괄호 표기법(obj['key'])의 차이는:
- 점 표기법: 키가 "유효한 식별자"일 때 편함 (
name,role) - 대괄호 표기법: 키에 공백/특수문자/동적 값이 들어갈 때 필요
const obj = {};
obj['full name'] = 'JavaScript';
const key = 'favorite-lang';
obj[key] = 'JS';
console.log(obj['full name']); // 'JavaScript'
console.log(obj['favorite-lang']); // 'JS'
삭제: delete
const user = {
id: 1,
name: '주니어',
role: 'dev',
};
delete user.role;
console.log(user);
// { id: 1, name: '주니어' }
delete obj.key는 해당 프로퍼티 자체를 제거한다.
프로퍼티 존재 여부: in / hasOwnProperty
어떤 키가 존재하는지 확인하고 싶을 때는 in 연산자나 hasOwnProperty를 쓴다.
in 연산자
const user = { id: 1, name: '주니어' };
console.log('id' in user); // true
console.log('role' in user); // false
in은 프로토타입 체인까지 포함해서 체크한다.
hasOwnProperty
const user = { id: 1 };
console.log(user.hasOwnProperty('id')); // true
console.log(user.hasOwnProperty('toString')); // false (프로토타입 쪽)
hasOwnProperty는 자기 자신의 프로퍼티만 확인- 라이브러리/프레임워크 코드 등에서 방어적으로 많이 쓰인다
순회: for...in + Object.keys / values / entries
Object는 for...of로는 직접 돌 수 없고,
보통 for...in + Object.xxx 조합으로 순회한다.
for...in (키 순회)
const user = {
id: 1,
name: '주니어',
role: 'dev',
};
for (const key in user) {
console.log(key, user[key]);
}
// id 1
// name 주니어
// role dev
주의할 점은
for...in은 열거 가능한(enumerable) 프로퍼티 + 프로토타입 체인까지 돈다- 보통은
hasOwnProperty와 함께 쓰는 패턴도 많다
for (const key in user) {
if (!user.hasOwnProperty(key)) continue;
console.log(key, user[key]);
}
Object.keys / values / entries
실무에서는 이 세 개가 자주 쓰인다.
Object.keys(obj)→ 키 배열Object.values(obj)→ 값 배열Object.entries(obj)→[key, value]쌍 배열
const user = {
id: 1,
name: '주니어',
role: 'dev',
};
console.log(Object.keys(user));
// ['id', 'name', 'role']
console.log(Object.values(user));
// [1, '주니어', 'dev']
console.log(Object.entries(user));
// [['id', 1], ['name', '주니어'], ['role', 'dev']]
이렇게 뽑아낸 배열은 다시 Array 메서드(map, filter 등)와 조합해서 쓰기 좋다.
Object.entries(user).forEach(([key, value]) => {
console.log(key, value);
});
JSON과 Object: stringify / parse
Object가 실무에서 많이 쓰이는 이유 중 하나는
JSON과 거의 1:1로 대응되기 때문이다.
- 서버 ↔ 클라이언트 통신 시 거의 항상 JSON 사용
- JSON 문자열 ↔ JS Object 변환은
JSON.stringify/JSON.parse
const user = {
id: 1,
name: '주니어',
role: 'dev',
};
const json = JSON.stringify(user);
console.log(json);
// '{"id":1,"name":"주니어","role":"dev"}'
const parsed = JSON.parse(json);
console.log(parsed.name); // '주니어'
그래서 응답 데이터, 요청 바디, 설정 파일 같은 것들은
거의 다 Object 리터럴로 표현된다.
복사: 얕은 복사 vs 깊은 복사
Object는 복사할 때 자주 실수한다.
특히 중첩 객체가 들어가면 더 그렇다.
얕은 복사 (shallow copy)
const user = {
id: 1,
profile: { name: '주니어' },
};
const shallow = { ...user };
shallow.profile.name = '시니어 지망생';
console.log(user.profile.name); // '시니어 지망생' (같이 바뀜)
바깥만 새 객체고, 안쪽 객체(profile)는 참조가 공유된다.
깊은 복사 (deep copy)
중첩 객체까지 통째로 복사하려면 깊은 복사가 필요하다.
ES2021+ 에서는 structuredClone을 쓸 수 있다.
const deep = structuredClone(user);
deep.profile.name = '완전 다른 사람';
console.log(user.profile.name); // '시니어 지망생'
console.log(deep.profile.name); // '완전 다른 사람'
중첩 구조(객체 안의 객체, 배열 안의 객체 등)를 많이 다루면
지금 이 복사가 얕은 복사인지 깊은 복사인지 의식하는 습관이 중요하다.
Map과의 간단 비교 (Object 이해용)
Object를 이해할 때, Map과의 차이를 같이 보면 더 잘 잡힌다.
| 관점 | Object | Map |
|---|---|---|
| 역할 느낌 | 데이터 레코드 / 모델 / 설정값 | 키-값 컬렉션 / 캐시 / 매핑 테이블 |
| 키 타입 | 문자열/심벌 | 아무 값이나 가능 (숫자, 객체, 배열 등) |
| 선언/생성 | 리터럴 {} 바로 사용 |
new Map() |
| 개수 | Object.keys(obj).length |
map.size |
| 순회 | for...in + Object.keys/values/entries |
for...of + keys/values/entries |
| JSON 직렬화 | 바로 JSON.stringify(obj) |
보통 Object/Array로 변환 후 직렬화 |
대략 이렇게 쓰면 편하다
- 서버 응답/요청, 설정, 도메인 모델 → Object
- 동적으로 키가 늘었다 줄었다 하는 캐시/매핑 테이블 → Map
Object 사용할 때 내 체크리스트
실제 코드 짤 때, 머릿속에서 대충 이렇게 생각한다.
- JSON으로 주고받는 데이터인가?
- 거의 항상 Object 리터럴
{}
- 거의 항상 Object 리터럴
- 이름 붙은 값 몇 개만 묶으면 끝나는 구조인가?
- Object가 더 단순하고 읽기 좋다
- 키 타입이 전부 문자열/식별자 형태인가?
- Object로 충분
- 중첩 객체가 많은가?
- 얕은 복사/깊은 복사(
structuredClone)를 의식하면서 작성
- 얕은 복사/깊은 복사(
- 키-값을 컬렉션처럼 자주 추가/삭제/검색하나?
- 이 시점부터는 Map도 한 번 고려해보기
오늘 내용 한 줄씩 다시 정리
- Object = 이름 붙은 값들의 묶음(데이터 구조)
- 리터럴
{}로 만들고,obj.key또는obj['key']로 접근한다. - Object는 기본적으로 이터러블이 아니라서, 순회는
for...in+Object.keys/values/entries조합이 기본이다. - JSON과 1:1로 맞물리기 때문에, 서버 데이터/설정값 표현에 최적화되어 있다.
- 복사할 때는 얕은 복사/깊은 복사를 구분해서 써야 한다.
- Map과의 관계를 이렇게 기억하면 편하다:
- 데이터 레코드 / JSON / 설정값 → Object
- 키-값 컬렉션 / 캐시 / 매핑 테이블 → Map
'FrontEnd > JavaScript' 카테고리의 다른 글
| JavaScript 컬렉션 - Array (0) | 2025.09.09 |
|---|---|
| JavaScript 컬렉션 - Map (0) | 2025.09.09 |
| JavaScript 반복문 한 번에 정리하기 (0) | 2025.09.09 |
| JavaScript new 연산자 (0) | 2025.09.09 |
| JavaScript 합성(Composition) - 상속보다 유연하게 객체 설계하기 (0) | 2025.09.09 |