JavaScriptとJSON:完全ガイド
JavaScriptでJSONを扱う方法。JSON.parse()、JSON.stringify()、実用例、ベストプラクティス、よくあるエラー。
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# JavaScriptとJSON:完全ガイド
JSONはJavaScript Object Notationの略で、JavaScriptと完璧に統合されています。
なぜJavaScriptとJSON?
JSONはもともとJavaScriptのオブジェクトリテラル構文から派生しました。
ネイティブサポート
JavaScriptには2つの組み込みメソッドがあります:
JSON.parse()- JSONをJavaScriptオブジェクトに変換JSON.stringify()- JavaScriptオブジェクトをJSONに変換
JSON.parse()
基本的な使い方
// JSON文字列
const jsonString = '{"name": "田中太郎", "age": 30}';
// JavaScriptオブジェクトに変換
const obj = JSON.parse(jsonString);
console.log(obj.name); // 田中太郎
console.log(obj.age); // 30
console.log(typeof obj); // object
配列のパース
const jsonArray = '["りんご", "バナナ", "オレンジ"]';
const fruits = JSON.parse(jsonArray);
console.log(fruits[0]); // りんご
console.log(Array.isArray(fruits)); // true
ネストされたオブジェクト
const jsonData = {
"user": {
"name": "田中太郎",
"age": 30,
"address": {
"city": "東京",
"zip": "100-0001"
}
}
}
;
const data = JSON.parse(jsonData);
console.log(data.user.address.city); // 東京
リバイバー関数
const jsonString = {
"name": "田中太郎",
"birthDate": "1995-05-15"
}
;
// リバイバー関数で日付を変換
const user = JSON.parse(jsonString, (key, value) => {
if (key === 'birthDate') {
return new Date(value);
}
return value;
});
console.log(user.birthDate instanceof Date); // true
JSON.stringify()
基本的な使い方
const user = {
name: '田中太郎',
age: 30,
city: '東京'
};
// JSON文字列に変換
const jsonString = JSON.stringify(user);
console.log(jsonString);
// {"name":"田中太郎","age":30,"city":"東京"}
フォーマット(美化)
const user = {
name: '田中太郎',
age: 30,
hobbies: ['読書', '旅行']
};
// インデント付き
const pretty = JSON.stringify(user, null, 2);
console.log(pretty);
/
{
"name": "田中太郎",
"age": 30,
"hobbies": [
"読書",
"旅行"
]
}
/
リプレーサー関数
const user = {
name: '田中太郎',
password: 'secret123',
age: 30
};
// パスワードを除外
const json = JSON.stringify(user, (key, value) => {
if (key === 'password') {
return undefined; // 除外
}
return value;
});
console.log(json);
// {"name":"田中太郎","age":30}
リプレーサー配列
const user = {
name: '田中太郎',
age: 30,
email: 'tanaka@example.com',
password: 'secret'
};
// 特定のプロパティのみ含める
const json = JSON.stringify(user, ['name', 'email']);
console.log(json);
// {"name":"田中太郎","email":"tanaka@example.com"}
データ型の変換
サポートされる型
const data = {
string: "こんにちは",
number: 42,
float: 3.14,
boolean: true,
null_value: null,
array: [1, 2, 3],
object: { key: "value" }
};
console.log(JSON.stringify(data));
サポートされない型
const data = {
func: function() { return 'hello'; }, // 除外
undef: undefined, // 除外
symbol: Symbol('test'), // 除外
date: new Date() // 文字列に変換
};
console.log(JSON.stringify(data));
// {"date":"2026-01-16T10:00:00.000Z"}
日付の処理
const data = {
name: '田中太郎',
created: new Date()
};
// シリアライズ
const json = JSON.stringify(data);
console.log(json);
// {"name":"田中太郎","created":"2026-01-16T10:00:00.000Z"}
// デシリアライズ
const parsed = JSON.parse(json, (key, value) => {
if (key === 'created') {
return new Date(value);
}
return value;
});
console.log(parsed.created instanceof Date); // true
Web API での使用
Fetch API
// GETリクエスト
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('エラー:', error);
});
// POSTリクエスト
const user = {
name: '田中太郎',
email: 'tanaka@example.com'
};
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
.then(response => response.json())
.then(data => {
console.log('成功:', data);
});
Async/Await
async function getUsers() {
try {
const response = await fetch('https://api.example.com/users');
const users = await response.json();
return users;
} catch (error) {
console.error('エラー:', error);
throw error;
}
}
// 使用
const users = await getUsers();
console.log(users);
エラーハンドリング
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
const data = await response.json();
return data;
} catch (error) {
if (error instanceof SyntaxError) {
console.error('無効なJSON:', error);
} else {
console.error('Fetchエラー:', error);
}
throw error;
}
}
ローカルストレージ
データの保存
// オブジェクトを保存
const user = {
name: '田中太郎',
age: 30,
preferences: {
theme: 'dark',
language: 'ja'
}
};
localStorage.setItem('user', JSON.stringify(user));
データの取得
// 取得とパース
const userJson = localStorage.getItem('user');
const user = JSON.parse(userJson);
console.log(user.name); // 田中太郎
ヘルパー関数
// 安全な保存と取得
const storage = {
set: (key, value) => {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
console.error('保存エラー:', error);
return false;
}
},
get: (key, defaultValue = null) => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('取得エラー:', error);
return defaultValue;
}
},
remove: (key) => {
localStorage.removeItem(key);
},
clear: () => {
localStorage.clear();
}
};
// 使用
storage.set('user', { name: '田中太郎' });
const user = storage.get('user');
ディープコピー
JSON でディープコピー
const original = {
name: '田中太郎',
address: {
city: '東京',
zip: '100-0001'
},
hobbies: ['読書', '旅行']
};
// ディープコピー
const copy = JSON.parse(JSON.stringify(original));
// 変更はコピーのみに影響
copy.address.city = '大阪';
console.log(original.address.city); // 東京
console.log(copy.address.city); // 大阪
制限事項
const obj = {
date: new Date(),
regex: /test/,
func: () => 'hello',
undef: undefined
};
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy);
// {date: "2026-01-16T10:00:00.000Z"}
// regex, func, undefは失われる
エラーハンドリング
Try-Catch
const invalidJson = '{"name": "田中太郎", "age": 30,}'; // 末尾のカンマ
try {
const data = JSON.parse(invalidJson);
console.log(data);
} catch (error) {
console.error('JSONパースエラー:', error.message);
// JSONパースエラー: Unexpected token } in JSON at position 32
}
安全なパース関数
function safeJsonParse(jsonString, defaultValue = null) {
try {
return JSON.parse(jsonString);
} catch (error) {
console.error('JSON parse error:', error);
return defaultValue;
}
}
// 使用
const data = safeJsonParse('invalid json', {});
console.log(data); // {}
検証関数
function isValidJson(string) {
try {
JSON.parse(string);
return true;
} catch (error) {
return false;
}
}
console.log(isValidJson('{"name": "田中"}')); // true
console.log(isValidJson('invalid')); // false
パフォーマンス最適化
大きなオブジェクトの処理
// 悪い例
for (let i = 0; i < 1000; i++) {
const json = JSON.stringify(largeObject);
}
// 良い例
const json = JSON.stringify(largeObject);
for (let i = 0; i < 1000; i++) {
// 事前にシリアライズされたJSONを使用
processJson(json);
}
ストリーミング(大きなJSON)
// Fetch with streaming
async function fetchLargeJson(url) {
const response = await fetch(url);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
result += decoder.decode(value, { stream: true });
}
return JSON.parse(result);
}
実用例
フォームデータの送信
const form = document.querySelector('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData);
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
console.log('成功:', result);
} catch (error) {
console.error('エラー:', error);
}
});
設定管理
class Config {
constructor() {
this.defaults = {
theme: 'light',
language: 'ja',
notifications: true
};
this.load();
}
load() {
const saved = localStorage.getItem('config');
this.settings = saved
? { ...this.defaults, ...JSON.parse(saved) }
: { ...this.defaults };
}
save() {
localStorage.setItem('config', JSON.stringify(this.settings));
}
get(key) {
return this.settings[key];
}
set(key, value) {
this.settings[key] = value;
this.save();
}
}
// 使用
const config = new Config();
config.set('theme', 'dark');
console.log(config.get('theme')); // dark
データキャッシング
class Cache {
constructor(expiryMinutes = 60) {
this.expiryMinutes = expiryMinutes;
}
set(key, data) {
const item = {
data,
expiry: Date.now() + (this.expiryMinutes 60 1000)
};
localStorage.setItem(key, JSON.stringify(item));
}
get(key) {
const item = localStorage.getItem(key);
if (!item) return null;
const { data, expiry } = JSON.parse(item);
if (Date.now() > expiry) {
localStorage.removeItem(key);
return null;
}
return data;
}
}
// 使用
const cache = new Cache(30); // 30分
cache.set('users', usersData);
const users = cache.get('users');
ベストプラクティス
1. 常にエラーハンドリング
// 良い
try {
const data = JSON.parse(jsonString);
processData(data);
} catch (error) {
handleError(error);
}
// 悪い
const data = JSON.parse(jsonString); // エラーで停止
2. Content-Typeヘッダー
// 良い
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
// 悪い(Content-Typeなし)
fetch('/api/data', {
method: 'POST',
body: JSON.stringify(data)
});
3. 循環参照を避ける
const obj = { name: '田中' };
obj.self = obj; // 循環参照
// エラー
JSON.stringify(obj); // TypeError: Converting circular structure to JSON
4. セキュリティ
// 悪い - eval使用(セキュリティリスク)
const obj = eval('(' + jsonString + ')');
// 良い - JSON.parse使用
const obj = JSON.parse(jsonString);
まとめ
クイックリファレンス
// パース
const obj = JSON.parse(jsonString);
const obj = JSON.parse(jsonString, reviverFunction);
// シリアライズ
const json = JSON.stringify(obj);
const json = JSON.stringify(obj, null, 2); // フォーマット
const json = JSON.stringify(obj, replacerFunction);
// Fetch API
const data = await fetch(url).then(r => r.json());
// ローカルストレージ
localStorage.setItem('key', JSON.stringify(obj));
const obj = JSON.parse(localStorage.getItem('key'));
JavaScriptのネイティブJSONサポートで、Web開発を効率化しましょう!