JSON.stringify() 는 JavaScript 값을 JSON 문자열로 바꿉니다 —— 요청 본문에 넣거나 파일에 저장하거나 localStorage 에 보관하기 위해. 단순해 보이지만 세 개의 인자, 특수 값 처리, 그리고 toJSON 훅이 개발자를 계속 걸려 넘어뜨립니다. 본 가이드는 JSON.stringify() 가 하는 모든 것, 다른 언어의 등가물, 피해야 할 함정을 다룹니다.
JSON.stringify 가 하는 일
값을 재귀적으로 순회하며 사양 준수 JSON 문자열을 만듭니다. 기본 출력은 압축이며 여분 공백이 없습니다:
const user = { name: "Ada", age: 36, active: true };
JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'항상 유효한 JSON 을 출력하므로 JSON 문자열을 손으로 만들지 마세요 —— concat 이나 템플릿 리터럴 사용은 [object Object] 오류 와 후행 콤마 오류 의 가장 큰 원인입니다.
세 개의 인자
JSON.stringify(value, replacer, space) 는 값과 더불어 대부분의 개발자가 절대 쓰지 않는 두 개의 옵션 인자 —— 그러나 강력합니다 —— 를 받습니다.
space —— pretty-print
세 번째 인자가 들여쓰기를 제어합니다. 공백 수로 숫자를, 또는 '\t' 같은 문자열을 넘기세요:
JSON.stringify(user, null, 2);
// {
// "name": "Ada",
// "age": 36,
// "active": true
// } 코드에서 JSON 을 pretty-print 하는 방식입니다 —— How to Format JSON 참고. 인자를 생략하거나 0 을 주면 minify; How to Minify JSON.
replacer —— 필터링과 변환
두 번째 인자는 포함할 키 배열이거나, 각 값을 변환하는 함수입니다:
// 허용 목록: 이 키만 남김
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'
// 함수: 한 필드를 마스크, 다른 필드는 버림
JSON.stringify(
{ name: "Ada", password: "secret", token: "abc" },
(key, value) => {
if (key === 'password') return '[REDACTED]';
if (key === 'token') return undefined; // undefined 반환 시 키 생략
return value;
},
);
// '{"name":"Ada","password":"[REDACTED]"}'toJSON 훅
값에 toJSON() 메서드가 있으면 JSON.stringify() 가 그것을 호출하고 반환값을 직렬화합니다. Date 객체가 자동으로 ISO 문자열이 되는 이유입니다:
JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}' ← Date.prototype.toJSON 실행
// 사용자 정의 toJSON 으로 직렬화
class Money {
constructor(cents) { this.cents = cents; }
toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'버려지거나 변환되는 것
JSON 에는 여섯 가지 타입만 있으므로 JSON 대응이 없는 JavaScript 값은 조용히 버려지거나 강제 변환됩니다 —— 왕복 버그의 자주 있는 원인:
| JavaScript 값 | JSON.stringify 의 결과 |
|---|---|
undefined(객체 안) | 키 생략 |
undefined(배열 안) | null |
| 함수 | 생략(객체) / null(배열) |
Symbol | 생략 |
NaN, Infinity | null |
Date | ISO 문자열(toJSON 경유) |
BigInt | TypeError 던짐 |
JSON 과 JavaScript 객체의 차이에 대한 완전 목록은 JSON vs JavaScript 객체.
흔한 함정
순환 참조는 던집니다
const a = {};
a.self = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON
// 수리: 본 객체를 추적하는 replacer, 또는 데이터 재구성BigInt 미지원
JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt
// 수리: 먼저 문자열로, 또는 replacer 추가
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
typeof v === 'bigint' ? v.toString() : v
);큰 정수는 왕복에서 정밀도를 잃습니다
253 을 넘는 숫자는 정확히 표현할 수 없습니다. 큰 정수 ID 를 stringify 한 뒤 parse 하면 값이 변할 수 있습니다. 그런 ID 는 문자열로 보관하세요.
인접 API: structuredClone, reviver, Stable Stringify
structuredClone—— 메모리 내 깊은 복사는JSON.parse(JSON.stringify(x))를 쓰지 마세요.structuredClone은Date,Map,Set,ArrayBuffer, 순환 참조를 네이티브로 처리하며 훨씬 빠릅니다.JSON.parse의reviver인자 는 여기replacer와 대칭. JSON 이 모델링하지 않는 타입의 무손실 왕복이 필요하면 짝지어 쓰세요 —— 예:replacer에서Date를 ISO 문자열로 인코딩,reviver에서 복원.- Stable-stringify 라이브러리(예:
json-stable-stringify,fast-json-stable-stringify) —— 키 삽입 순서와 무관하게 같은 문자열을 만듭니다. 출력이 해시·서명·텍스트 비교될 때 사용(정식 버전은 RFC 8785 / JCS).
다른 언어의 Stringify
# Python
import json
json.dumps({"name": "Ada"}) # 압축
json.dumps({"name": "Ada"}, indent=2) # 미화
json.dumps({"name": "Ada"}, separators=(',', ':')) # minify
// Go
import "encoding/json"
b, _ := json.Marshal(map[string]string{"name": "Ada"})
// Ruby
require 'json'
{ name: "Ada" }.to_json브라우저에서 JSON Stringify
JSON 값을 코드, DB 컬럼, 셸 명령에 임베드하려고 문자열 리터럴로 이스케이프해야 하나요? fixjson 의 JSON Stringify 도구 가 즉시, 브라우저에서, 어떤 서버로도 데이터를 보내지 않고 처리합니다.
자주 묻는 질문
JSON.stringify 로 pretty-print 하려면?
세 번째 인자: JSON.stringify(value, null, 2) 가 2 공백 들여쓰기, '\t' 가 탭. How to Format JSON.
왜 JSON.stringify 가 속성을 버리나요?
undefined, 함수, Symbol 값의 속성은 JSON 표현이 없어 생략됩니다. replacer 를 쓰거나 먼저 변환하세요.
BigInt 가 포함된 값을 stringify 하려면?
JSON.stringify() 는 BigInt 에서 던집니다. bigint 값에 .toString() 을 호출하는 replacer 를 제공하고 반대쪽에서 의도적으로 다시 파싱하세요.
JSON.stringify 와 JSON.parse 의 차이는?
stringify 는 값을 JSON 문자열로, parse 는 JSON 문자열을 값으로 되돌립니다. 서로 역. 파싱 함정은 JavaScript 에서 깨진 JSON 처리.
Map 이나 Set 을 JSON.stringify 하려면?
기본적으로 둘 다 "{}" 로 직렬화됩니다 —— Map 은 자체 열거 가능한 속성이 없고 Set 은 빈 객체로 stringify 됩니다. 먼저 JSON 친화적 모양으로 변환하거나(또는 replacer 사용):
// Map → [key, value] 쌍의 배열(왕복 가능)
JSON.stringify([...myMap]);
// 또는 replacer 로:
JSON.stringify({ data: myMap }, (k, v) =>
v instanceof Map ? Object.fromEntries(v) :
v instanceof Set ? [...v] : v
); 돌아올 때는 JSON.parse 의 reviver 에서 new Map(arr) / new Set(arr) 로 재구축하세요. 순수 JSON 에는 Map/Set 타입이 없기 때문입니다.
지금 시도해 보세요
- JSON Stringify —— 브라우저에서 JSON 값을 문자열 리터럴로 이스케이프
- How to Format JSON ——
space인자로 pretty-print - How to Minify JSON —— 압축 형태와 가치
- JSON 이란? —— stringify 가 만들 수 있는 6 가지 타입