JSON Formatter JavaScript — JSON.stringify()
無料の JSON整形ツール をブラウザで直接使用 — インストール不要。
JSON整形ツール をオンラインで試す →Node.js で API レスポンスをデバッグするとき、圧縮された JSON の壁が最初の障壁になります—— JSON.stringify(data, null, 2) を一度呼び出すだけで構造が即座に読めるようになります。 JavaScript で JSON をフォーマットするのに、 ランタイム以外は何も必要ありません: JSON.stringify はすべてのブラウザと Node.js 環境に組み込まれており、インストール不要です。 コードを書かずに素早く結果が欲しい場合は、ToolDeckの JSON Formatter が即座に対応します。 このガイドでは実践的な内容をすべてカバーします: space パラメータ、replacer の配列と関数、 Date・ BigInt・ 循環参照の処理、Node.js(18+)でのJSONファイルの読み書き、CLIでの整形表示、 そして本番シリアライゼーション向けの fast-json-stringify ライブラリ。
- ✓JSON.stringify(data, null, 2) はすべてのブラウザと Node.js に組み込まれています——インストール不要。
- ✓replacer パラメータは配列(キーのホワイトリスト)または関数(値の変換)を受け付けます——機密フィールドのマスクに使用できます。
- ✓DateオブジェクトはtoJSON()経由でISO 8601文字列に自動シリアライズされます;BigIntはTypeErrorをスローし、カスタムreplacerが必要です。
- ✓循環参照はTypeErrorをスローします——replacer関数内のseenセットで修正するか、flattedライブラリを使用してください。
- ✓CLIでの整形表示には node -p "JSON.stringify(require('./file.json'),null,2)" を使用——追加ツール不要。
JSONフォーマットとは?
JSONフォーマット(pretty-printingとも呼ばれる)は、コンパクトに圧縮されたJSON文字列を 一貫したインデントと改行を持つ人間が読みやすいレイアウトに変換します。 基礎データはまったく同じ——空白文字だけが変わります。 コンパクトなJSONはバイト数が重要なネットワーク転送に最適で、 フォーマットされたJSONはデバッグ、コードレビュー、ログ調査に最適です。 JavaScript の JSON.stringify() は space パラメータを切り替えるだけで、1回の呼び出しで両方に対応できます。
{"orderId":"ord_8f2a91bc","status":"shipped","items":[{"sku":"HDMI-4K-2M","qty":2,"unitPrice":12.99}],"total":25.98}{
"orderId": "ord_8f2a91bc",
"status": "shipped",
"items": [
{
"sku": "HDMI-4K-2M",
"qty": 2,
"unitPrice": 12.99
}
],
"total": 25.98
}JSON.stringify() — 組み込みフォーマッター
JSON.stringify() は、ブラウザ、Node.js、Deno、Bun——すべての JavaScript 環境のグローバル関数で、 インポート不要です。第3引数の space がインデントを制御します:数値を渡すとそのレベルごとにスペースが入り、 文字列 '\t' を渡すとタブになります。省略(または null を渡す)するとコンパクトな1行出力になります。
const serverConfig = {
host: "api.payments.internal",
port: 8443,
workers: 4,
tls: { enabled: true, cert: "/etc/ssl/certs/api.pem" },
rateLimit: { requestsPerMinute: 1000, burst: 50 }
}
console.log(JSON.stringify(serverConfig, null, 2))
// {
// "host": "api.payments.internal",
// "port": 8443,
// "workers": 4,
// "tls": {
// "enabled": true,
// "cert": "/etc/ssl/certs/api.pem"
// },
// "rateLimit": {
// "requestsPerMinute": 1000,
// "burst": 50
// }
// }space パラメータは数値(1〜10スペース)または文字列を受け付けます。 タブ文字を渡すと、多くのエディタや diff ツールが好む出力になります。 以下は設定ファイルにフォーマット済みJSONを書き込む際に私がよく使うパターンです:
const telemetryEvent = {
eventId: "evt_3c7f9a2b",
service: "checkout-api",
severity: "warn",
latencyMs: 342,
region: "ap-northeast-1",
tags: ["payment", "timeout", "retry"]
}
// 2スペースインデント(JSプロジェクトで最も一般的)
JSON.stringify(telemetryEvent, null, 2)
// タブインデント(一部のlinterや設定ツールが好む)
JSON.stringify(telemetryEvent, null, '\t')
// コンパクト——空白なし(ネットワーク転送用)
JSON.stringify(telemetryEvent)
// {"eventId":"evt_3c7f9a2b","service":"checkout-api",...}undefined、関数、 Symbol の値は出力から警告なしに省略されます。 プロパティ値が undefined の場合、 そのキーはシリアライズされた文字列にまったく現れません—— オプションフィールドを持つオブジェクトをログに記録する際によくあるバグの原因です。Replacer関数 — 出力のフィルタリングと変換
JSON.stringify() の第2引数が replacer です。2つの形式があります: 特定のキーをホワイトリストする配列と、 すべてのキー/値ペアに対して呼び出されてフィルタリング・変換・マスクができる関数です。 素早いサブセットが必要なときは配列形式、ログ記録前に機密データをマスクする必要があるときは関数形式を使います。
配列Replacer — 特定のキーをホワイトリスト
const order = {
orderId: "ord_8f2a91bc",
customer: {
id: "usr_4421",
email: "tanaka@example.jp",
passwordHash: "bcrypt:$2b$12$XKzV..."
},
items: [{ sku: "HDMI-4K-2M", qty: 2, unitPrice: 12.99 }],
createdAt: "2026-03-10T14:22:00Z"
}
// ログ出力には安全なフィールドのみ含める
const safeLog = JSON.stringify(order, ["orderId", "items", "createdAt"], 2)
// {
// "orderId": "ord_8f2a91bc",
// "items": [{ "sku": "HDMI-4K-2M", "qty": 2, "unitPrice": 12.99 }],
// "createdAt": "2026-03-10T14:22:00Z"
// }
// passwordHashとcustomer.emailは除外される関数Replacer — 値の変換
const auditRecord = {
requestId: "req_7d2e91",
user: { id: "usr_4421", email: "tanaka@example.jp", apiKey: "sk-live-eKx9..." },
action: "update_billing",
timestamp: new Date("2026-03-10T14:22:00Z"),
durationMs: 87
}
function safeReplacer(key, value) {
// シークレットや個人情報に見えるフィールドをマスク
if (key === "apiKey") return "[REDACTED]"
if (key === "email") return value.replace(/(?<=.{2}).+(?=@)/, "***")
return value
}
console.log(JSON.stringify(auditRecord, safeReplacer, 2))
// {
// "requestId": "req_7d2e91",
// "user": { "id": "usr_4421", "email": "ta***@example.jp", "apiKey": "[REDACTED]" },
// "action": "update_billing",
// "timestamp": "2026-03-10T14:22:00.000Z",
// "durationMs": 87
// }this が現在のキーを含むオブジェクトに設定されて呼び出されます。 最初の呼び出しでは空文字列がキーとして渡され、シリアライズされる値全体が値として渡されます—— 通常のシリアライゼーションを続けるにはそのまま返してください。シリアライズできない型の処理
すべての JavaScript の値が JSON に綺麗にマップされるわけではありません。 各型の挙動を理解することで、本番コードでの無言のデータ損失や予期しないランタイムエラーを防げます。
Date — toJSON()による自動処理
Date オブジェクトには ISO 8601 文字列を返す toJSON() メソッドが実装されています。 JSON.stringify() はシリアライズ前に自動的に toJSON() を呼び出すため、カスタム処理は不要です。
const webhook = {
eventType: "payment.succeeded",
occurredAt: new Date("2026-03-10T14:22:00Z"),
processedAt: new Date()
}
JSON.stringify(webhook, null, 2)
// {
// "eventType": "payment.succeeded",
// "occurredAt": "2026-03-10T14:22:00.000Z",
// "processedAt": "2026-03-10T14:22:01.347Z"
// }
// toJSON()メソッドを持つオブジェクトは同様に処理されます:
const custom = { toJSON: () => "custom-value", hidden: 42 }
JSON.stringify(custom) // '"custom-value"'カスタムクラス — toJSON()の実装
任意のクラスで toJSON() メソッドを実装でき、 JSON.stringify() はシリアライゼーション時に自動的に呼び出します。 コードベース全体で登場するドメイン型に対しては、グローバル replacer より簡潔です。
class Money {
constructor(amount, currency) {
this.amount = amount
this.currency = currency
}
toJSON() {
// JSON.stringifyが自動的に呼び出す
return { amount: this.amount, currency: this.currency, formatted: `${this.currency} ${this.amount.toFixed(2)}` }
}
}
class OrderId {
constructor(id) { this.id = id }
toJSON() { return this.id } // 純粋な文字列としてシリアライズ
}
const invoice = {
invoiceId: new OrderId('inv_8f2a91bc'),
subtotal: new Money(199.00, 'JPY'),
tax: new Money(15.92, 'JPY'),
issuedAt: new Date('2026-03-10T14:22:00Z')
}
JSON.stringify(invoice, null, 2)
// {
// "invoiceId": "inv_8f2a91bc",
// "subtotal": { "amount": 199, "currency": "JPY", "formatted": "JPY 199.00" },
// "tax": { "amount": 15.92, "currency": "JPY", "formatted": "JPY 15.92" },
// "issuedAt": "2026-03-10T14:22:00.000Z"
// }toJSON() は replacer 関数より優先されます。 両方が存在する場合、toJSON() が先に実行され—— replacer は元のクラスインスタンスではなく、すでに変換された値を受け取ります。BigInt — ReplacerなしだとTypeError
// これはスローします: TypeError: Do not know how to serialize a BigInt
// JSON.stringify({ sessionId: 9007199254741234n })
// 修正: replacerでBigIntを文字列に変換
function bigIntReplacer(_key, value) {
return typeof value === 'bigint' ? value.toString() : value
}
const metrics = {
requestCount: 9007199254741234n, // Number.MAX_SAFE_INTEGERを超える
service: "ingestion-worker",
region: "ap-northeast-1"
}
JSON.stringify(metrics, bigIntReplacer, 2)
// {
// "requestCount": "9007199254741234",
// "service": "ingestion-worker",
// "region": "ap-northeast-1"
// }循環参照 — seenセットなしだとTypeError
// これはスローします: TypeError: Converting circular structure to JSON
// const node = { id: "n1" }; node.self = node; JSON.stringify(node)
// 修正: WeakSetで参照済みオブジェクトを追跡
function circularReplacer() {
const seen = new WeakSet()
return function (_key, value) {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]'
seen.add(value)
}
return value
}
}
const parent = { id: "node_parent", label: "root" }
const child = { id: "node_child", parent }
parent.child = child // 循環参照
JSON.stringify(parent, circularReplacer(), 2)
// {
// "id": "node_parent",
// "label": "root",
// "child": { "id": "node_child", "parent": "[Circular]" }
// }
// または: npm install flatted
// import { stringify } from 'flatted'
// stringify(parent) // 循環参照をネイティブに処理JSON.stringify() パラメータリファレンス
3つのパラメータはすべてのモダンな JavaScript ランタイムで完全サポートされています。 デフォルト値ではコンパクトな1行JSONが出力されます——読みやすい出力には明示的にパラメータを渡してください。
ファイルとAPIレスポンスのJSONフォーマット
Node.js(18+)では、JSON設定ファイルを再フォーマットしたり、デバッグのためにAPIレスポンスを整形表示したりすることがよくあります。 どちらのパターンも同じ2ステップのアプローチです: JSON.parse() で生テキストをパースし、 JSON.stringify() で再シリアライズします。
JSON設定ファイルの読み込みと再書き込み
import { readFileSync, writeFileSync } from 'fs'
try {
const raw = readFileSync('./config/database.json', 'utf8')
const config = JSON.parse(raw)
writeFileSync('./config/database.json', JSON.stringify(config, null, 2))
console.log('設定ファイルの再フォーマットに成功しました')
} catch (err) {
console.error('設定ファイルの再フォーマットに失敗しました:', err.message)
// ファイルに無効なJSONが含まれていると JSON.parse が SyntaxError をスロー
// ファイルが存在しない場合 readFileSync が ENOENT をスロー
}非同期ファイル再フォーマット(fs/promises)
import { readFile, writeFile } from 'fs/promises'
async function reformatJson(filePath) {
const raw = await readFile(filePath, 'utf8')
const parsed = JSON.parse(raw)
const formatted = JSON.stringify(parsed, null, 2)
await writeFile(filePath, formatted, 'utf8')
return { keys: Object.keys(parsed).length }
}
// 使用例
const { keys } = await reformatJson('./config/feature-flags.json')
console.log(`トップレベルキー ${keys} 個を再フォーマットしました`)fetch()レスポンスのJSONを整形表示
Node.js 18+ またはブラウザで API クライアントを構築・デバッグする際、 レスポンスボディを整形表示するのがサーバーの返り値を素早く把握する最善の方法です。 標準パターンは response.json()(パース済みオブジェクト)を JSON.stringify() に渡すことです。 ハッシュ計算や逐語的なログ記録のために生の文字列が最初に必要な場合は、 response.text() から JSON.parse() を使ってください。
// パターン1: response.json() → 整形表示
async function debugEndpoint(url) {
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }
})
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`)
const data = await res.json()
console.log(JSON.stringify(data, null, 2))
}
await debugEndpoint('https://api.stripe.com/v1/charges?limit=3')// パターン2: response.text() → パース → フォーマット
// 生のレスポンスと整形表示の両方をログに残したい場合に使用
async function inspectRawResponse(url) {
const res = await fetch(url)
const raw = await res.text()
console.log('生レスポンスの長さ:', raw.length)
try {
const parsed = JSON.parse(raw)
console.log('フォーマット済み:')
console.log(JSON.stringify(parsed, null, 2))
} catch {
console.error('レスポンスが有効なJSONではありません:', raw.slice(0, 200))
}
}コマンドラインでの整形表示
Node.js は追加ツールなしでターミナルから JSON を整形表示するのに十分な機能を持っています。 以下のワンライナーは CI スクリプト、デプロイパイプライン、シェルエイリアスで役立ちます。 さらに高速なインタラクティブ使用には jq をインストールしてください——コマンドラインでのJSON操作のデファクトスタンダードです。
# node -p(print)を使ってpackage.jsonを整形表示
node -p "JSON.stringify(require('./package.json'), null, 2)"
# 標準入力から整形表示(パイプ対応、CIで動作)
echo '{"port":3000,"env":"production"}' | node -e "
const d = require('fs').readFileSync(0, 'utf8')
console.log(JSON.stringify(JSON.parse(d), null, 2))
"
# ファイルに保存されたAPIレスポンスを整形表示
cat api-response.json | node -e "
process.stdin.setEncoding('utf8')
let s = ''
process.stdin.on('data', c => s += c)
process.stdin.on('end', () => console.log(JSON.stringify(JSON.parse(s), null, 2)))
"# Pythonフォールバック(macOSと多くのLinuxディストリビューションにプリインストール)
cat api-response.json | python3 -m json.tool
# jq — 最も高速で機能豊富(brew install jq / apt install jq)
cat api-response.json | jq .
# jq — 整形表示とフィルタリングを一度に
cat api-response.json | jq '.data.users[] | {id, email}'"type": "module" を含む)でNode.jsを実行している場合、 ワンライナーでは require() が使えません。 代わりに --input-type=module と fs.readFileSync を使うか、 上記のように CommonJS スニペットを使った node -e に切り替えてください。ターミナルにいない場合——Postmanのレスポンスやログファイルを貼り付ける場合——ToolDeckの JSON Formatter なら、シンタックスハイライトと組み込みバリデーション付きで、貼り付け・フォーマット・コピーを一ステップで行えます。
高性能な代替手段 — fast-json-stringify
fast-json-stringify は JSON Schema から専用のシリアライザー関数を生成します。 データの形状を事前に知っているため、型チェックをスキップして再帰的な走査の代わりに文字列結合を使えます—— ベンチマークでは大きくて繰り返しの多いペイロードに対して JSON.stringify() より通常2〜5倍のスループット向上を示します。 プロファイラートレースでシリアライゼーションコストが見えてくる高頻度APIルートで使用しています。
npm install fast-json-stringify
import fastJson from 'fast-json-stringify'
const serializeTelemetryEvent = fastJson({
title: 'TelemetryEvent',
type: 'object',
properties: {
eventId: { type: 'string' },
service: { type: 'string' },
severity: { type: 'string', enum: ['info', 'warn', 'error'] },
latencyMs: { type: 'integer' },
timestamp: { type: 'string' },
region: { type: 'string' }
},
required: ['eventId', 'service', 'severity', 'latencyMs', 'timestamp']
})
const event = {
eventId: 'evt_3c7f9a2b',
service: 'checkout-api',
severity: 'warn',
latencyMs: 342,
timestamp: new Date().toISOString(),
region: 'ap-northeast-1'
}
const json = serializeTelemetryEvent(event)
// '{"eventId":"evt_3c7f9a2b","service":"checkout-api","severity":"warn",...}'fast-json-stringify は構造化データの本番シリアライゼーション向けに設計されています—— 常にコンパクトな出力を生成します(整形表示なし)。 開発中に人間が読める出力が必要な場合は、通常通り JSON.stringify(data, null, 2) を使ってください。シンタックスハイライト付きのターミナル出力
Node.js に組み込まれた util.inspect() は、ターミナル表示に最適化されたカラフルで人間が読みやすい出力を生成します。 循環参照と BigInt をネイティブに処理し、ネストされたオブジェクトを任意の深さまで再帰的にレンダリングします。 出力は有効な JSON ではありません——JavaScript 構文を使います(関数や Symbol を省略せずレンダリングするなど)。 Node.js デバッグスクリプトに最適ですが、API レスポンスやファイル出力には不向きです。
import { inspect } from 'util'
const payload = {
requestId: "req_7d2e91",
user: { id: "usr_4421", roles: ["admin", "billing"] },
metadata: { ipAddress: "203.0.113.42", userAgent: "Mozilla/5.0" },
createdAt: new Date()
}
// depth: null → すべてのネストレベルを展開; colors: true → ANSIターミナルカラー
console.log(inspect(payload, { colors: true, depth: null })) util.inspect() の出力を使わないでください。 その出力は有効な JSON ではなく、 JSON.parse() を呼び出す下流のシステムでパースエラーが発生します。 インタラクティブなターミナルデバッグのみに使用してください。大きなJSONファイルの処理
JSON.parse() はパース前にファイル全体をメモリに読み込みます——小さなペイロードなら問題ありませんが、 データベースエクスポート、アプリケーションログダンプ、分析バッチなど 50〜100 MB を超えるファイルには現実的ではありません。 このような場合、Node.js Streams と stream-json ライブラリを使えば、ヒープを使い果たさずにレコードを1つずつ処理できます。
stream-jsonでのストリーミングパース
npm install stream-json
import { pipeline } from 'stream/promises'
import { createReadStream } from 'fs'
import { parser } from 'stream-json'
import { streamArray } from 'stream-json/streamers/StreamArray.js'
// events.json = 何百万ものオブジェクトの配列 — メモリに完全には読み込まれない
await pipeline(
createReadStream('./events.json'),
parser(),
streamArray(),
async function* (source) {
for await (const { value: event } of source) {
if (event.severity === 'error') {
console.log(JSON.stringify(event, null, 2))
}
}
}
)NDJSON / JSON Lines — 追加依存関係なし
NDJSON(改行区切りJSON)は1行に1つのJSONオブジェクトを格納し、 Kafkaエクスポート、BigQuery出力、構造化ログパイプラインでよく使われます。 Node.js 組み込みの readline があれば、サードパーティパッケージなしで処理できます。
import { createReadStream } from 'fs'
import { createInterface } from 'readline'
// 形式: 1行に1つのJSONオブジェクト(ログ、Kafkaエクスポート、BigQuery)
const rl = createInterface({
input: createReadStream('./logs.ndjson'),
crlfDelay: Infinity
})
for await (const line of rl) {
if (!line.trim()) continue
const entry = JSON.parse(line)
if (entry.level === 'error') {
console.log(JSON.stringify(entry, null, 2))
}
}JSON.parse() からストリーミングに切り替えてください。 NDJSON / JSON Lines には readline を使ってください——追加依存関係は不要です。よくある間違い
以下の4つの間違いは、コードレビューや本番バグレポートで繰り返し登場します。 それぞれが JSON.stringify() の見落としやすい微妙な挙動に関わっており、事後のデバッグが困難です。
問題: undefined の値を持つオブジェクトプロパティはJSON出力から完全に省略されます——警告もエラーも出ません。オブジェクトにオプションフィールドが存在する場合、見えないデータ損失が発生します。
解決策: シリアライズ出力に必ず含める必要がある意図的な欠如値には null を使用してください。undefined はJSONから除外すべきフィールドにのみ使ってください。
const userProfile = {
userId: "usr_4421",
displayName: "田中太郎",
avatarUrl: undefined, // 警告なしに消える
bio: undefined // 警告なしに消える
}
JSON.stringify(userProfile, null, 2)
// { "userId": "usr_4421", "displayName": "田中太郎" }
// avatarUrlとbioが消えた——警告なしconst userProfile = {
userId: "usr_4421",
displayName: "田中太郎",
avatarUrl: null, // 明示的な欠如 — 出力に含まれる
bio: null // 明示的な欠如 — 出力に含まれる
}
JSON.stringify(userProfile, null, 2)
// {
// "userId": "usr_4421",
// "displayName": "田中太郎",
// "avatarUrl": null,
// "bio": null
// }問題: BigInt値をJSON.stringify()に渡すと実行時にTypeErrorがスローされます。これは静かな省略ではなくハードクラッシュです——数値フィールドがNumber.MAX_SAFE_INTEGERを超えると本番環境で表面化します。
解決策: シリアライゼーション前にBigInt値を文字列に変換するreplacer関数を使用してください。またはJSON.stringify()に渡す前にデータ層でBigIntを文字列またはNumberに変換してください。
const session = {
sessionId: 9007199254741234n, // BigIntリテラル
userId: "usr_4421",
startedAt: "2026-03-10T14:00:00Z"
}
JSON.stringify(session, null, 2)
// Uncaught TypeError: Do not know how to serialize a BigIntfunction bigIntReplacer(_key, value) {
return typeof value === 'bigint' ? value.toString() : value
}
const session = {
sessionId: 9007199254741234n,
userId: "usr_4421",
startedAt: "2026-03-10T14:00:00Z"
}
JSON.stringify(session, bigIntReplacer, 2)
// {
// "sessionId": "9007199254741234",
// "userId": "usr_4421",
// "startedAt": "2026-03-10T14:00:00Z"
// }問題: 自分自身を参照するオブジェクト——DOMツリー、連結リスト、一部のORMの結果セットに多い——をJSON.stringify()に渡すとTypeErrorがスローされます。このエラーはシリアライゼーション時にのみ発生し、循環参照が作られた場所からはるかに離れた場所で起こることが多いです。
解決策: WeakSetを使ったreplacer関数で循環参照を検出・置換するか、循環構造をネイティブに処理するflattedライブラリをインストールしてください。
const dept = { id: "dept_eng", name: "エンジニアリング部" }
const team = { id: "team_frontend", dept }
dept.teams = [team] // 循環: dept → team → dept
JSON.stringify(dept, null, 2)
// Uncaught TypeError: Converting circular structure to JSONimport { stringify } from 'flatted' // npm install flatted
const dept = { id: "dept_eng", name: "エンジニアリング部" }
const team = { id: "team_frontend", dept }
dept.teams = [team]
// flattedが循環参照を処理——注意: 出力はflatted形式で標準JSONではない
stringify(dept)
// または標準JSON出力が必要な場合はWeakSetベースのreplacerを使用:
function circularReplacer() {
const seen = new WeakSet()
return (_key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]'
seen.add(value)
}
return value
}
}
JSON.stringify(dept, circularReplacer(), 2)問題: JSON.stringify()にspaceとして10より大きい値を渡してもエラーはスローされません——値は警告なしに10に切り捨てられます。深いネストに20スペースインデントを期待する開発者は10しか得られず、生成されたファイルで予期しないフォーマットになります。
解決策: 最大インデントは10スペースです。深い構造には2スペースインデント(JavaScriptプロジェクトで最も一般的な慣習)を使用し、折りたたみ可能なエディタでナビゲーションしてください。
const deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }
// 20スペースインデントを期待——しかしspaceは10に切り捨てられる
JSON.stringify(deepConfig, null, 20)
// JSON.stringify(deepConfig, null, 10)と同じ出力
// エラーなし、警告なし——静かに切り捨てconst deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }
// 2(ほとんどのプロジェクト)または4スペースを使用——10を超えない
JSON.stringify(deepConfig, null, 2)
// {
// "server": {
// "tls": {
// "certs": {
// "primary": "/etc/ssl/api.pem"
// }
// }
// }
// }JSON.stringify vs 代替手段 — クイック比較
状況によって適切なツールが異なります。replacer を使った JSON.stringify は依存関係なしでほとんどの本番ユースケースをカバーします。 カラー出力が必要で有効なJSONが不要な場合、 util.inspect は素早いターミナルデバッグの正しい選択です。fast-json-stringify はプロファイリングでシリアライゼーションコストが見える高スループットルートで効果を発揮します—— それ以外の場合、スキーマ管理のオーバーヘッドは割に合いません。
よくある質問
JavaScriptでJSONをきれいに表示するには?
JSON.stringify(data, null, 2) を呼び出します——第3引数がインデントを制御します。スペースには 2 や 4 を、タブには "\t" を渡してください。インポートやインストールは不要です:JSON はブラウザと Node.js を含むすべての JavaScript 環境のグローバルオブジェクトです。
const config = { host: "api.payments.internal", port: 8443, tls: true }
console.log(JSON.stringify(config, null, 2))
// {
// "host": "api.payments.internal",
// "port": 8443,
// "tls": true
// }JSON.stringify() の space パラメータの役割は?
space パラメータは出力のインデントを制御します。数値(1〜10)を渡すとそのレベルごとにスペースが入り、"\t" のような文字列を渡すとタブ文字が使われます。10 を超える値は暗黙的に 10 に切り捨てられます。null、0、または省略するとコンパクトな1行のJSONが出力されます。
const data = { service: "payments", version: 3, active: true }
JSON.stringify(data, null, 2) // 2スペースインデント
JSON.stringify(data, null, 4) // 4スペースインデント
JSON.stringify(data, null, '\t') // タブインデント
JSON.stringify(data) // コンパクト: {"service":"payments","version":3,"active":true}JSON.stringify() が一部の値に対して undefined を返すのはなぜ?
JSON.stringify は undefined、関数、Symbol の値を持つオブジェクトプロパティを警告なしに省略します——これらの型には JSON 表現がありません。トップレベルの値自体が undefined の場合、関数は undefined を返します(文字列 "undefined" ではありません)。出力に必ず含める必要があるオプションフィールドには undefined の代わりに null を使用してください。
const event = {
traceId: "tr_9a2f",
handler: () => {}, // 関数 — 省略される
requestId: undefined, // undefined — 省略される
sessionId: Symbol("s"), // Symbol — 省略される
status: "ok"
}
JSON.stringify(event, null, 2)
// { "traceId": "tr_9a2f", "status": "ok" }JSONフォーマット時にDateオブジェクトはどう扱う?
Date オブジェクトには ISO 8601 文字列を返す組み込みの toJSON() メソッドがあるため、JSON.stringify は自動的に処理します。日付用のカスタム replacer は不要です——シリアライズされた値は "2026-03-10T14:22:00.000Z" のような文字列になります。
const order = {
orderId: "ord_8f2a91bc",
placedAt: new Date("2026-03-10T14:22:00Z"),
total: 42.98
}
JSON.stringify(order, null, 2)
// {
// "orderId": "ord_8f2a91bc",
// "placedAt": "2026-03-10T14:22:00.000Z",
// "total": 42.98
// }JavaScriptでJSON文字列(オブジェクトではない)をフォーマットするには?
まず JSON.parse() で文字列をパースし、次に JSON.stringify() で再シリアライズします。素早くデバッグするために、2つの呼び出しを1行でチェーンできます。
const raw = '{"endpoint":"/api/v2/users","timeout":30,"retry":true}'
const formatted = JSON.stringify(JSON.parse(raw), null, 2)
console.log(formatted)
// {
// "endpoint": "/api/v2/users",
// "timeout": 30,
// "retry": true
// }ブラウザでJSON.stringify()は使える?
使えます。JSON は IE8 以降のすべての最新ブラウザに組み込まれたグローバルです——script タグやインポートは不要です。DevTools コンソールを開いて直接 JSON.stringify() を呼び出せます。Node.js バージョンと完全に同じ動作で、パラメータシグネチャも BigInt や循環参照に関する制限も同じです。
// Chrome、Firefox、Safari、Edge で動作——インポート不要
const payload = { userId: "usr_7b3c", action: "checkout", cart: ["SKU-001", "SKU-002"] }
copy(JSON.stringify(payload, null, 2)) // copy() は DevTools ヘルパー関数JavaScriptは完全なコントロールを提供します——replacer関数、カスタムtoJSON()、Node.jsでの大きなファイル処理。フォーマットされたスニペットを確認または共有するだけでよい場合、 ToolDeckのJSON Formatter が最速の方法です:JSONを貼り付けるだけで、環境設定なしにフォーマット・ハイライトされた結果が得られます。
関連ツール
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Marcus specialises in JavaScript performance, build tooling, and the inner workings of the V8 engine. He has spent years profiling and optimising React applications, working on bundler configurations, and squeezing every millisecond out of critical rendering paths. He writes about Core Web Vitals, JavaScript memory management, and the tools developers reach for when performance really matters.