[Javascript] JSON
JS JSON, JSON.stringify, JSON.parse
정의
JSON (JavaScript Object Notation) 은 데이터 교환 형식. JS 의 객체 리터럴과 비슷하지만 엄격한 문법.
JSON.stringify(value): JS 값 → JSON 문자열JSON.parse(text): JSON 문자열 → JS 값
stringify
JSON.stringify({ a: 1, b: [2, 3] })
// '{"a":1,"b":[2,3]}'
JSON.stringify({ a: 1 }, null, 2)
// pretty-print, 2-space indent
// {
// "a": 1
// }
parse
JSON.parse('{"a":1}') // { a: 1 }
JSON.parse('[1, 2, 3]') // [1, 2, 3]
JSON.parse('null') // null
JSON.parse('true') // true
JSON.parse('"hello"') // 'hello'
replacer (stringify)
JSON.stringify({ a: 1, password: 'secret' }, (key, value) => {
return key === 'password' ? undefined : value;
});
// '{"a":1}'
// 또는 array (allowlist)
JSON.stringify(obj, ['a', 'b']); // a, b 만 포함
reviver (parse)
JSON.parse(text, (key, value) => {
if (key === 'date') return new Date(value);
return value;
});
date / BigInt 등 표준 외 타입 복원에 유용.
누락되는 값들
stringify 가 무시하거나 변환하는 값:
| 입력 | 결과 |
|---|---|
undefined (값) | 키 제외 |
undefined (배열 원소) | null |
Symbol (값) | 키 제외 |
function | 키 제외 |
NaN, Infinity | null |
Date | toISOString() 호출 → string |
BigInt | ❌ TypeError |
| 순환 참조 | ❌ TypeError |
JSON.stringify({
a: undefined,
b: Symbol(),
c: () => {},
d: NaN,
e: new Date(),
f: 1n, // ❌
});
// '{"d":null,"e":"2024-..."}' (a, b, c 제외)
toJSON 메서드
객체에 toJSON 메서드가 있으면 stringify 가 호출.
class Money {
constructor(amount) { this.amount = amount; }
toJSON() {
return `$${this.amount.toFixed(2)}`;
}
}
JSON.stringify(new Money(99.9)); // '"$99.90"'
Date 가 ISO string 되는 것도 이 메커니즘.
깊은 복사 (제한적)
const copy = JSON.parse(JSON.stringify(obj));
장점: 단순. 단점:
- Date → string 으로 변환됨
- function, undefined, Symbol 누락
- BigInt, 순환 참조 에러
깊은 복사는 structuredClone(obj) 권장 (ES2022+).
자주 쓰는 패턴
API 통신
const response = await fetch('/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const json = await response.json(); // 내부적으로 JSON.parse
localStorage
localStorage.setItem('user', JSON.stringify(user));
const user = JSON.parse(localStorage.getItem('user'));
디버깅 출력
console.log(JSON.stringify(complexObj, null, 2));
보안 (민감 정보 제거)
function sanitize(obj) {
return JSON.parse(JSON.stringify(obj, (k, v) =>
['password', 'token', 'apiKey'].includes(k) ? undefined : v
));
}
함정
1. 한국어 escape
JSON.stringify({ name: '한글' })
// '{"name":"한글"}' (UTF-8 그대로)
// 옛 환경 호환을 위해 ASCII 만 원한다면 직접 escape
2. 정수 정밀도
JSON.parse('9007199254740993') // 9007199254740992 (정밀도 손실)
큰 정수는 JSON 문자열 → BigInt 수동 변환.
3. 순환 참조
const a = {};
a.self = a;
JSON.stringify(a) // ❌ TypeError
해법: replacer 로 순환 감지 또는 외부 라이브러리.
4. 키 순서
JSON.parse(JSON.stringify(obj))
// 객체 키 순서가 보존되긴 하지만 표준은 보장 안 함
비교/해시에 키 순서를 의존하지 말 것.
JSON5 / JSONC
{
// 주석 가능
"a": 1,
"b": 2, // trailing comma
}
JSON 의 확장 (주석, 후행 쉼표). 표준이 아니라 라이브러리 필요. tsconfig.json 이 JSONC 사용.
💬 댓글