← ブログに戻る

JavaScriptとJSON:完全ガイド

JavaScriptでJSONを扱う方法。JSON.parse()、JSON.stringify()、実用例、ベストプラクティス、よくあるエラー。

Big JSON Team12 分で読めますprogramming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

12 分読む

# 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開発を効率化しましょう!

Share:

関連記事

Read in English