<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_JSON</id>
	<title>JavaScriptの基礎 - JSON - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_JSON"/>
	<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_JSON&amp;action=history"/>
	<updated>2026-07-02T09:51:05Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://mochiuwiki.e2.valueserver.jp/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_JSON&amp;diff=14383&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == JSON (JavaScript Object Notation) は、JavaScriptのオブジェクトリテラル構文を基にした軽量なテキスト形式のデータ交換フォーマットである。&lt;br&gt; 言語非依存の仕様として設計されており、JavaScriptに限らず多くのプログラミング言語でデータの送受信に広く使用されている。&lt;br&gt; &lt;br&gt; JavaScriptでJSONを操作するための組み込みオブジェクト &lt;code&gt;JSON&lt;/code&gt;…」</title>
		<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_JSON&amp;diff=14383&amp;oldid=prev"/>
		<updated>2026-02-20T22:52:15Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == JSON (JavaScript Object Notation) は、JavaScriptのオブジェクトリテラル構文を基にした軽量なテキスト形式のデータ交換フォーマットである。&amp;lt;br&amp;gt; 言語非依存の仕様として設計されており、JavaScriptに限らず多くのプログラミング言語でデータの送受信に広く使用されている。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; JavaScriptでJSONを操作するための組み込みオブジェクト &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt;…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
JSON (JavaScript Object Notation) は、JavaScriptのオブジェクトリテラル構文を基にした軽量なテキスト形式のデータ交換フォーマットである。&amp;lt;br&amp;gt;&lt;br /&gt;
言語非依存の仕様として設計されており、JavaScriptに限らず多くのプログラミング言語でデータの送受信に広く使用されている。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
JavaScriptでJSONを操作するための組み込みオブジェクト &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; は、2つのメソッドを提供する。&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt;&lt;br /&gt;
*: JSON文字列をJavaScriptの値 (オブジェクト、配列、プリミティブ) に変換する。&lt;br /&gt;
* &amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt;&lt;br /&gt;
*: JavaScriptの値をJSON文字列に変換 (シリアライズ) する。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;シリアライズ時には、JavaScriptの全ての型がJSONとして表現できるわけではないことに注意が必要である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;undefined&amp;lt;/code&amp;gt;、関数、&amp;lt;code&amp;gt;Symbol&amp;lt;/code&amp;gt; はオブジェクトプロパティから削除され、&amp;lt;code&amp;gt;NaN&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;Infinity&amp;lt;/code&amp;gt; は &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; に変換される。&amp;lt;br&amp;gt;&lt;br /&gt;
また、&amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt; オブジェクトはISO 8601形式の文字列に変換されるが、&amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt; では自動的に &amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt; に戻されない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
JSONを利用したディープコピー (&amp;lt;code&amp;gt;JSON.parse(JSON.stringify())&amp;lt;/code&amp;gt;) は手軽な手法であるが、上記の型の制約がある。&amp;lt;br&amp;gt;&lt;br /&gt;
現代のWebブラウザやNode.js環境では、&amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;Map&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;Set&amp;lt;/code&amp;gt;、循環参照を正しく処理できる &amp;lt;code&amp;gt;structuredClone()&amp;lt;/code&amp;gt; が利用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Tauri v2では、&amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; によるIPC通信でフロントエンドとRustバックエンド間のデータがJSONを介して自動的にシリアライズ・デシリアライズされる。&amp;lt;br&amp;gt;&lt;br /&gt;
Rust側では &amp;lt;code&amp;gt;serde&amp;lt;/code&amp;gt; クレートにより、構造体のフィールド名変換 (snake_case / camelCase) も自動化される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JSONの基本 ==&lt;br /&gt;
==== JSONの構文規則 ====&lt;br /&gt;
JSONは厳格な構文規則を持つテキストフォーマットである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;JavaScriptのオブジェクトリテラルとは異なる点があるため、注意が必要である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
主な構文規則を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ JSONの主な構文規則&lt;br /&gt;
! 規則 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| キー名は必ず二重引用符 (&amp;quot;) で囲む&lt;br /&gt;
|&lt;br /&gt;
* 単一引用符 (&amp;#039;) は使用不可&lt;br /&gt;
* &amp;lt;code&amp;gt;{ &amp;quot;name&amp;quot;: &amp;quot;Alice&amp;quot; }&amp;lt;/code&amp;gt; は有効&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;{ name: &amp;quot;Alice&amp;quot; }&amp;lt;/code&amp;gt; は無効&lt;br /&gt;
|-&lt;br /&gt;
| 文字列値は二重引用符で囲む || &amp;lt;code&amp;gt;&amp;quot;hello&amp;quot;&amp;lt;/code&amp;gt; は有効&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&amp;#039;hello&amp;#039;&amp;lt;/code&amp;gt; は無効&lt;br /&gt;
|-&lt;br /&gt;
| 末尾カンマは使用不可 || 配列やオブジェクトの最後の要素の後にカンマがあると &amp;lt;code&amp;gt;SyntaxError&amp;lt;/code&amp;gt; が発生する。&lt;br /&gt;
|-&lt;br /&gt;
| コメントは使用不可 || JavaScript のような &amp;lt;code&amp;gt;// コメント&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;/* コメント */&amp;lt;/code&amp;gt; は無効&lt;br /&gt;
|-&lt;br /&gt;
| 数値は整数または浮動小数点数のみ || &amp;lt;code&amp;gt;Infinity&amp;lt;/code&amp;gt; および &amp;lt;code&amp;gt;NaN&amp;lt;/code&amp;gt; はJSONとして不正な値である。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
有効なJSONの例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    &amp;quot;age&amp;quot;: 30,&lt;br /&gt;
    &amp;quot;isActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;address&amp;quot;: null,&lt;br /&gt;
    &amp;quot;scores&amp;quot;: [85, 92, 78],&lt;br /&gt;
    &amp;quot;profile&amp;quot;: {&lt;br /&gt;
       &amp;quot;city&amp;quot;: &amp;quot;Tokyo&amp;quot;,&lt;br /&gt;
       &amp;quot;country&amp;quot;: &amp;quot;Japan&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== JSONの型 と JavaScript型の対応 ====&lt;br /&gt;
JSONが扱える型は6種類であり、JavaScriptの全ての型とは対応していない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ JSONの型とJavaScript型の対応&lt;br /&gt;
! JSON型 !! JavaScript型 !! 備考&lt;br /&gt;
|-&lt;br /&gt;
| string || string || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| number || number || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| boolean || boolean || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| null || null || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| object || object (プレーンオブジェクト) || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| array || Array || 1対1対応&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || undefined || シリアライズ時にプロパティ削除または配列要素がnullに変換&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || Date || ISO 8601文字列に変換&amp;lt;br&amp;gt;逆変換は行われない。&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || Function || シリアライズ時にプロパティ削除または配列要素がnullに変換&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || Map / Set || {} (空オブジェクト) または [] (空配列) に変換&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || RegExp || {} (空オブジェクト) に変換&lt;br /&gt;
|-&lt;br /&gt;
| (非対応) || BigInt || &amp;lt;u&amp;gt;TypeError&amp;lt;/u&amp;gt; が発生する。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JSON.parse ==&lt;br /&gt;
==== 基本的な使用方法 ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.parse(text)&amp;lt;/code&amp;gt; は、JSON文字列をJavaScriptの値に変換するメソッドである。&amp;lt;br&amp;gt;&lt;br /&gt;
引数に渡した文字列が有効なJSONでない場合は &amp;lt;code&amp;gt;SyntaxError&amp;lt;/code&amp;gt; をスローする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
基本的な使用例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // JSON文字列をオブジェクトに変換する&lt;br /&gt;
 const obj = JSON.parse(&amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;age&amp;quot;:30}&amp;#039;);&lt;br /&gt;
 console.log(obj.name);  // &amp;quot;Alice&amp;quot;&lt;br /&gt;
 console.log(obj.age);   // 30&lt;br /&gt;
 &lt;br /&gt;
 // 配列のJSONを変換する&lt;br /&gt;
 const arr = JSON.parse(&amp;#039;[1, 2, 3]&amp;#039;);&lt;br /&gt;
 console.log(arr);       // [1, 2, 3]&lt;br /&gt;
 &lt;br /&gt;
 // プリミティブ値のJSONを変換する&lt;br /&gt;
 const num = JSON.parse(&amp;#039;42&amp;#039;);&lt;br /&gt;
 console.log(num);       // 42&lt;br /&gt;
 &lt;br /&gt;
 const str = JSON.parse(&amp;#039;&amp;quot;hello&amp;quot;&amp;#039;);&lt;br /&gt;
 console.log(str);       // &amp;quot;hello&amp;quot;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== reviver関数 ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.parse(text, reviver)&amp;lt;/code&amp;gt; の第2引数にreviver関数を指定することにより、各プロパティの値を変換しながらパースできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
下表に、reviver関数の仕様を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ reviver関数の仕様&lt;br /&gt;
! 項目 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| シグネチャ || &amp;lt;code&amp;gt;function reviver(key, value)&amp;lt;/code&amp;gt; の形式で定義する。&amp;lt;br&amp;gt;&amp;lt;u&amp;gt;key&amp;lt;/u&amp;gt; はプロパティ名 (文字列)、&amp;lt;u&amp;gt;value&amp;lt;/u&amp;gt; は変換前の値である。&lt;br /&gt;
|-&lt;br /&gt;
| 処理順序 || 深さ優先探索で葉から根へ処理される。&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;u&amp;gt;undefined&amp;lt;/u&amp;gt; を返した場合 || そのプロパティは削除される。&lt;br /&gt;
|-&lt;br /&gt;
| ルートオブジェクトの処理 || 空文字列 (&amp;lt;u&amp;gt;&amp;quot;&amp;quot;&amp;lt;/u&amp;gt;) をキーとして最後に処理される。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
reviver関数の主な活用例として、JSON文字列として保存されたDateオブジェクトの復元がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const jsonString = &amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;createdAt&amp;quot;:&amp;quot;2024-01-15T10:30:00.000Z&amp;quot;}&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const data = JSON.parse(jsonString, (key, value) =&amp;gt; {&lt;br /&gt;
    // ISO 8601形式の文字列をDateオブジェクトに変換する&lt;br /&gt;
    if (typeof value === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; /^\d{4}-\d{2}-\d{2}T/.test(value)) {&lt;br /&gt;
       return new Date(value);&lt;br /&gt;
    }&lt;br /&gt;
    return value;&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(data.name);                       // &amp;quot;Alice&amp;quot;&lt;br /&gt;
 console.log(data.createdAt);                  // Dateオブジェクト&lt;br /&gt;
 console.log(data.createdAt instanceof Date);  // true&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
プロパティを削除するreviver関数の例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const json = &amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;password&amp;quot;:&amp;quot;secret&amp;quot;,&amp;quot;age&amp;quot;:30}&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const filtered = JSON.parse(json, (key, value) =&amp;gt; {&lt;br /&gt;
    // パスワードプロパティを除去する&lt;br /&gt;
    if (key === &amp;#039;password&amp;#039;) return undefined;&lt;br /&gt;
    return value;&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(filtered);  // { name: &amp;quot;Alice&amp;quot;, age: 30 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== エラーハンドリング ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt; は無効なJSON文字列が渡された場合に &amp;lt;u&amp;gt;SyntaxError&amp;lt;/u&amp;gt; をスローする。&amp;lt;br&amp;gt;&lt;br /&gt;
そのため、外部から取得したJSON文字列をパースする際は &amp;lt;code&amp;gt;try / catch&amp;lt;/code&amp;gt; で処理することが推奨される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 function safeParseJSON(text) {&lt;br /&gt;
    try {&lt;br /&gt;
       return { success: true, data: JSON.parse(text) };&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       if (error instanceof SyntaxError) {&lt;br /&gt;
          console.error(&amp;#039;無効なJSON文字列:&amp;#039;, error.message);&lt;br /&gt;
       }&lt;br /&gt;
       return { success: false, data: null };&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 有効なJSONの場合&lt;br /&gt;
 const result1 = safeParseJSON(&amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;}&amp;#039;);&lt;br /&gt;
 console.log(result1.success);  // true&lt;br /&gt;
 console.log(result1.data);     // { name: &amp;quot;Alice&amp;quot; }&lt;br /&gt;
 &lt;br /&gt;
 // 無効なJSONの場合 (末尾カンマ)&lt;br /&gt;
 const result2 = safeParseJSON(&amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,}&amp;#039;);&lt;br /&gt;
 console.log(result2.success);  // false&lt;br /&gt;
 console.log(result2.data);     // null&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JSON.stringify ==&lt;br /&gt;
==== 基本的な使用方法 ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.stringify(value, replacer, space)&amp;lt;/code&amp;gt; は、JavaScriptの値をJSON文字列に変換するメソッドである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;&lt;br /&gt;
*: シリアライズ対象の値&lt;br /&gt;
* &amp;lt;code&amp;gt;replacer&amp;lt;/code&amp;gt;&lt;br /&gt;
*: フィルタリング関数 または 配列 (省略可能)&lt;br /&gt;
* &amp;lt;code&amp;gt;space&amp;lt;/code&amp;gt;&lt;br /&gt;
*: インデントの指定 (省略可能)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
基本的な使用例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const obj = { name: &amp;quot;Alice&amp;quot;, age: 30, active: true };&lt;br /&gt;
 &lt;br /&gt;
 // 基本的なシリアライズ&lt;br /&gt;
 const json = JSON.stringify(obj);&lt;br /&gt;
 console.log(json);                 // &amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;age&amp;quot;:30,&amp;quot;active&amp;quot;:true}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // 配列のシリアライズ&lt;br /&gt;
 const arr = [1, &amp;quot;hello&amp;quot;, true, null];&lt;br /&gt;
 console.log(JSON.stringify(arr));  // &amp;#039;[1,&amp;quot;hello&amp;quot;,true,null]&amp;#039;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== replacer引数 ====&lt;br /&gt;
===== replacer関数 =====&lt;br /&gt;
replacerとして関数を指定した場合、オブジェクトの各プロパティに対してその関数が呼び出される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;undefined&amp;lt;/u&amp;gt;、関数、または &amp;lt;u&amp;gt;Symbol&amp;lt;/u&amp;gt; を返したプロパティは出力から除外される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const user = {&lt;br /&gt;
    id: 1,&lt;br /&gt;
    name: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    password: &amp;quot;secret123&amp;quot;,&lt;br /&gt;
    apiKey: &amp;quot;key-xxxx-yyyy&amp;quot;&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // 機密情報を除外するreplacer関数&lt;br /&gt;
 const safeJson = JSON.stringify(user, (key, value) =&amp;gt; {&lt;br /&gt;
    if (key === &amp;#039;password&amp;#039; || key === &amp;#039;apiKey&amp;#039;) return undefined;&lt;br /&gt;
 &lt;br /&gt;
    return value;&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(safeJson);   // &amp;#039;{&amp;quot;id&amp;quot;:1,&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // 数値を文字列に変換するreplacer関数&lt;br /&gt;
 const data = { count: 42, label: &amp;quot;items&amp;quot; };&lt;br /&gt;
 const converted = JSON.stringify(data, (key, value) =&amp;gt; {&lt;br /&gt;
    if (typeof value === &amp;#039;number&amp;#039;) return String(value);&lt;br /&gt;
 &lt;br /&gt;
    return value;&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(converted);  // &amp;#039;{&amp;quot;count&amp;quot;:&amp;quot;42&amp;quot;,&amp;quot;label&amp;quot;:&amp;quot;items&amp;quot;}&amp;#039;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
===== replacer配列 =====&lt;br /&gt;
replacerとして文字列の配列を指定した場合、配列に含まれるキーのプロパティのみが出力される。(ホワイトリスト方式)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const user = {&lt;br /&gt;
    id: 1,&lt;br /&gt;
    name: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    email: &amp;quot;alice@example.com&amp;quot;,&lt;br /&gt;
    password: &amp;quot;secret&amp;quot;,&lt;br /&gt;
    role: &amp;quot;admin&amp;quot;&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // id, name, emailのみを含む&lt;br /&gt;
 const publicInfo = JSON.stringify(user, [&amp;#039;id&amp;#039;, &amp;#039;name&amp;#039;, &amp;#039;email&amp;#039;]);&lt;br /&gt;
 console.log(publicInfo);  // &amp;#039;{&amp;quot;id&amp;quot;:1,&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;email&amp;quot;:&amp;quot;alice@example.com&amp;quot;}&amp;#039;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== space引数 ====&lt;br /&gt;
&amp;lt;code&amp;gt;space&amp;lt;/code&amp;gt; 引数を指定することにより、出力JSONに読みやすいインデントを追加できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 数値を指定した場合&lt;br /&gt;
*: 指定したスペース数でインデントされる。(最大10)&lt;br /&gt;
* 文字列を指定した場合&lt;br /&gt;
*: その文字列でインデントされる。(最大10文字)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const obj = { name: &amp;quot;Alice&amp;quot;, scores: [85, 92, 78] };&lt;br /&gt;
 &lt;br /&gt;
 // 数値でインデント&lt;br /&gt;
 console.log(JSON.stringify(obj, null, 2));&lt;br /&gt;
 // {&lt;br /&gt;
 //   &amp;quot;name&amp;quot;: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
 //   &amp;quot;scores&amp;quot;: [&lt;br /&gt;
 //     85,&lt;br /&gt;
 //     92,&lt;br /&gt;
 //     78&lt;br /&gt;
 //   ]&lt;br /&gt;
 // }&lt;br /&gt;
 &lt;br /&gt;
 // タブ文字でインデント&lt;br /&gt;
 console.log(JSON.stringify(obj, null, &amp;#039;\t&amp;#039;));&lt;br /&gt;
 // {&lt;br /&gt;
 // 	&amp;quot;name&amp;quot;: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
 // 	&amp;quot;scores&amp;quot;: [...]&lt;br /&gt;
 // }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== toJSON()メソッド ====&lt;br /&gt;
オブジェクトに &amp;lt;code&amp;gt;toJSON()&amp;lt;/code&amp;gt; メソッドが定義されている場合、&amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; はオブジェクト自体ではなく &amp;lt;code&amp;gt;toJSON()&amp;lt;/code&amp;gt; の戻り値をシリアライズする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt; オブジェクトはこの仕組みを組み込みで持っており、&amp;lt;code&amp;gt;toISOString()&amp;lt;/code&amp;gt; と同等の結果を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // DateオブジェクトのtoJSON()&lt;br /&gt;
 const date = new Date(&amp;#039;2024-01-15T10:30:00.000Z&amp;#039;);&lt;br /&gt;
 console.log(JSON.stringify(date));  // &amp;#039;&amp;quot;2024-01-15T10:30:00.000Z&amp;quot;&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // カスタムクラスでのtoJSON()実装&lt;br /&gt;
 class Temperature {&lt;br /&gt;
    constructor(celsius) {&lt;br /&gt;
       this.celsius = celsius;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    get fahrenheit() {&lt;br /&gt;
       return this.celsius * 9 / 5 + 32;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    toJSON() {&lt;br /&gt;
       // シリアライズ時にcelsiusとfahrenheitの両方を含める&lt;br /&gt;
       return {&lt;br /&gt;
          celsius: this.celsius,&lt;br /&gt;
          fahrenheit: this.fahrenheit&lt;br /&gt;
       };&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const temp = new Temperature(100);&lt;br /&gt;
 console.log(JSON.stringify(temp));&lt;br /&gt;
 // &amp;#039;{&amp;quot;celsius&amp;quot;:100,&amp;quot;fahrenheit&amp;quot;:212}&amp;#039;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== シリアライズの注意点 ==&lt;br /&gt;
==== 無視・変換される値 ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; のシリアライズ時に、JavaScriptの値がどのように変換されるか下表に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ シリアライズ時の値の変換&lt;br /&gt;
! 型 !! オブジェクトプロパティ値 !! 配列要素 !! トップレベル&lt;br /&gt;
|-&lt;br /&gt;
| undefined || 省略 (プロパティが削除) || null || undefined (文字列化されない)&lt;br /&gt;
|-&lt;br /&gt;
| function || 省略 (プロパティが削除) || null || undefined (文字列化されない)&lt;br /&gt;
|-&lt;br /&gt;
| Symbol || 省略 (プロパティが削除) || null || undefined (文字列化されない)&lt;br /&gt;
|-&lt;br /&gt;
| NaN || &amp;quot;null&amp;quot; (文字列) || &amp;quot;null&amp;quot; (文字列) || &amp;quot;null&amp;quot; (文字列)&lt;br /&gt;
|-&lt;br /&gt;
| Infinity || &amp;quot;null&amp;quot; (文字列) || &amp;quot;null&amp;quot; (文字列) || &amp;quot;null&amp;quot; (文字列)&lt;br /&gt;
|-&lt;br /&gt;
| BigInt || TypeError が発生 || TypeError が発生 || TypeError が発生&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
具体的な動作例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const obj = {&lt;br /&gt;
    name: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    fn: function() {},          // 省略される&lt;br /&gt;
    sym: Symbol(&amp;quot;id&amp;quot;),          // 省略される&lt;br /&gt;
    undef: undefined,           // 省略される&lt;br /&gt;
    nan: NaN,                   // null になる&lt;br /&gt;
    inf: Infinity               // null になる&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 console.log(JSON.stringify(obj));&lt;br /&gt;
 // &amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;nan&amp;quot;:null,&amp;quot;inf&amp;quot;:null}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // 配列要素では、nullに変換される&lt;br /&gt;
 const arr = [1, undefined, function() {}, Symbol(&amp;quot;x&amp;quot;), NaN];&lt;br /&gt;
 console.log(JSON.stringify(arr));&lt;br /&gt;
 // &amp;#039;[1,null,null,null,null]&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // BigIntはTypeErrorをスローする&lt;br /&gt;
 try {&lt;br /&gt;
    JSON.stringify({ value: 42n });&lt;br /&gt;
 }&lt;br /&gt;
 catch (e) {&lt;br /&gt;
    console.log(e instanceof TypeError);  // true&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Dateオブジェクト ====&lt;br /&gt;
&amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt; オブジェクトは &amp;lt;code&amp;gt;toJSON()&amp;lt;/code&amp;gt; メソッドを持ち、&amp;lt;code&amp;gt;toISOString()&amp;lt;/code&amp;gt; と同等のISO 8601形式の文字列に自動変換される。&amp;lt;br&amp;gt;&lt;br /&gt;
ただし、&amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt; は文字列をDateオブジェクトに戻す機能を持たないため、reviver関数を使用して明示的に変換する必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // シリアライズ : DateがISO文字列に変換される&lt;br /&gt;
 const event = {&lt;br /&gt;
    title: &amp;quot;ミーティング&amp;quot;,&lt;br /&gt;
    date: new Date(&amp;quot;2024-06-15T09:00:00.000Z&amp;quot;)&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 const json = JSON.stringify(event);&lt;br /&gt;
 console.log(json);&lt;br /&gt;
 // &amp;#039;{&amp;quot;title&amp;quot;:&amp;quot;ミーティング&amp;quot;,&amp;quot;date&amp;quot;:&amp;quot;2024-06-15T09:00:00.000Z&amp;quot;}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // デシリアライズ : reviver関数でDateを復元する&lt;br /&gt;
 const restored = JSON.parse(json, (key, value) =&amp;gt; {&lt;br /&gt;
    if (typeof value === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; /^\d{4}-\d{2}-\d{2}T/.test(value)) {&lt;br /&gt;
       return new Date(value);&lt;br /&gt;
    }&lt;br /&gt;
    return value;&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(restored.date instanceof Date);  // true&lt;br /&gt;
 console.log(restored.date.getFullYear());    // 2024&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 循環参照 ====&lt;br /&gt;
オブジェクトが循環参照を持つ場合、&amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; は &amp;lt;u&amp;gt;TypeError&amp;lt;/u&amp;gt; をスローする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;WeakSet&amp;lt;/code&amp;gt; を使用することで、循環参照を検出してその箇所を除外するreplacer関数を定義できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 循環参照を持つオブジェクト&lt;br /&gt;
 const obj = { name: &amp;quot;Alice&amp;quot; };&lt;br /&gt;
 obj.self = obj;  // 循環参照&lt;br /&gt;
 &lt;br /&gt;
 try {&lt;br /&gt;
    JSON.stringify(obj);&lt;br /&gt;
 }&lt;br /&gt;
 catch (e) {&lt;br /&gt;
    console.log(e instanceof TypeError);  // true&lt;br /&gt;
    console.log(e.message);               // &amp;quot;Converting circular structure to JSON&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // WeakSetを使用した循環参照の回避&lt;br /&gt;
 const getCircularReplacer = () =&amp;gt; {&lt;br /&gt;
    const seen = new WeakSet();&lt;br /&gt;
    return (key, value) =&amp;gt; {&lt;br /&gt;
       if (typeof value === &amp;#039;object&amp;#039; &amp;amp;&amp;amp; value !== null) {&lt;br /&gt;
          if (seen.has(value)) {&lt;br /&gt;
             return undefined;  // 循環参照をundefinedで置換して除外する&lt;br /&gt;
          }&lt;br /&gt;
          seen.add(value);&lt;br /&gt;
       }&lt;br /&gt;
       return value;&lt;br /&gt;
    };&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 const safeJson = JSON.stringify(obj, getCircularReplacer());&lt;br /&gt;
 console.log(safeJson);  // &amp;#039;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;}&amp;#039;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Map / Set / RegExp ====&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;code&amp;gt;Map&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;Set&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;RegExp&amp;lt;/code&amp;gt; はいずれもJSONで直接表現できないため、シリアライズ時に情報が失われる。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;これらの型を正しくシリアライズするには、事前に変換処理が必要である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // MapとSetはそのままでは空オブジェクト / 配列になる&lt;br /&gt;
 const map = new Map([[&amp;quot;key1&amp;quot;, &amp;quot;value1&amp;quot;], [&amp;quot;key2&amp;quot;, &amp;quot;value2&amp;quot;]]);&lt;br /&gt;
 const set = new Set([1, 2, 3]);&lt;br /&gt;
 const regex = /hello/gi;&lt;br /&gt;
 &lt;br /&gt;
 console.log(JSON.stringify({ map, set, regex }));&lt;br /&gt;
 // &amp;#039;{&amp;quot;map&amp;quot;:{},&amp;quot;set&amp;quot;:{},&amp;quot;regex&amp;quot;:{}}&amp;#039;  // 全て空オブジェクト&lt;br /&gt;
 &lt;br /&gt;
 // Mapのシリアライズ: Object.fromEntries() または スプレッド構文で変換する&lt;br /&gt;
 const mapAsObject = Object.fromEntries(map);&lt;br /&gt;
 console.log(JSON.stringify(mapAsObject));&lt;br /&gt;
 // &amp;#039;{&amp;quot;key1&amp;quot;:&amp;quot;value1&amp;quot;,&amp;quot;key2&amp;quot;:&amp;quot;value2&amp;quot;}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // Mapをエントリ配列として保存する場合&lt;br /&gt;
 const mapAsArray = [...map];&lt;br /&gt;
 console.log(JSON.stringify(mapAsArray));&lt;br /&gt;
 // &amp;#039;[[&amp;quot;key1&amp;quot;,&amp;quot;value1&amp;quot;],[&amp;quot;key2&amp;quot;,&amp;quot;value2&amp;quot;]]&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // Setのシリアライズ: 配列に変換する&lt;br /&gt;
 const setAsArray = [...set];&lt;br /&gt;
 console.log(JSON.stringify(setAsArray));&lt;br /&gt;
 // &amp;#039;[1,2,3]&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // RegExpのシリアライズ: sourceとflagsを保存する&lt;br /&gt;
 const regexObj = { source: regex.source, flags: regex.flags };&lt;br /&gt;
 console.log(JSON.stringify(regexObj));&lt;br /&gt;
 // &amp;#039;{&amp;quot;source&amp;quot;:&amp;quot;hello&amp;quot;,&amp;quot;flags&amp;quot;:&amp;quot;gi&amp;quot;}&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // RegExpの復元&lt;br /&gt;
 const restoredRegex = new RegExp(regexObj.source, regexObj.flags);&lt;br /&gt;
 console.log(restoredRegex);  // /hello/gi&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ディープコピー ==&lt;br /&gt;
==== JSON.parse(JSON.stringify())によるディープコピー ====&lt;br /&gt;
&amp;lt;code&amp;gt;JSON.parse(JSON.stringify(obj))&amp;lt;/code&amp;gt; は、オブジェクトのディープコピーを作成する最も単純な手法である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;外部ライブラリなしで定義でき、パフォーマンスも良好であるが、JSONで表現できない型は失われる点に注意が必要である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const original = {&lt;br /&gt;
    name: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    scores: [85, 92, 78],&lt;br /&gt;
    address: {&lt;br /&gt;
       city: &amp;quot;Tokyo&amp;quot;,&lt;br /&gt;
       country: &amp;quot;Japan&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // ディープコピーを作成する&lt;br /&gt;
 const copy = JSON.parse(JSON.stringify(original));&lt;br /&gt;
 &lt;br /&gt;
 // コピーを変更しても元のオブジェクトに影響しない&lt;br /&gt;
 copy.scores.push(100);&lt;br /&gt;
 copy.address.city = &amp;quot;Osaka&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 console.log(original.scores);        // [85, 92, 78] (変更されない)&lt;br /&gt;
 console.log(original.address.city);  // &amp;quot;Tokyo&amp;quot; (変更されない)&lt;br /&gt;
 &lt;br /&gt;
 // 注意 : JSONで表現できない型は失われる&lt;br /&gt;
 const withSpecialTypes = {&lt;br /&gt;
    date: new Date(&amp;quot;2024-01-01&amp;quot;),&lt;br /&gt;
    fn: function() {},&lt;br /&gt;
    undef: undefined,&lt;br /&gt;
    regex: /hello/&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 const copied = JSON.parse(JSON.stringify(withSpecialTypes));&lt;br /&gt;
 console.log(typeof copied.date);    // &amp;quot;string&amp;quot; (Dateが文字列になる)&lt;br /&gt;
 console.log(copied.fn);             // undefined (関数が削除)&lt;br /&gt;
 console.log(copied.undef);          // undefined (プロパティが存在しない)&lt;br /&gt;
 console.log(copied.regex);          // {} (RegExpが空オブジェクトになる)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== structuredClone()との比較 ====&lt;br /&gt;
&amp;lt;code&amp;gt;structuredClone()&amp;lt;/code&amp;gt; は、Structured Clone アルゴリズムを使用してオブジェクトのディープコピーを作成する組み込み関数である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Date&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;Map&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;Set&amp;lt;/code&amp;gt;、循環参照を正しく処理できる点がJSON方式と異なる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Webブラウザの対応状況として、Chrome 98+, Firefox 94+, Safari 15.4+, Node.js 17.0+ 以降で使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ ディープコピー手法の比較&lt;br /&gt;
! データ型 !! JSON方式 !! structuredClone()&lt;br /&gt;
|-&lt;br /&gt;
| 基本型 (string, number, boolean, null) || 正常にコピー || 正常にコピー&lt;br /&gt;
|-&lt;br /&gt;
| Date || 文字列に変換 (型が変わる) || Dateオブジェクトとして正しくコピー&lt;br /&gt;
|-&lt;br /&gt;
| Map || 空オブジェクト {} (情報が失われる) || Mapとして正しくコピー&lt;br /&gt;
|-&lt;br /&gt;
| Set || 空オブジェクト {} (情報が失われる) || Setとして正しくコピー&lt;br /&gt;
|-&lt;br /&gt;
| RegExp || 空オブジェクト {} (情報が失われる) || フラグを含めて正しくコピー&lt;br /&gt;
|-&lt;br /&gt;
| 関数 || 削除される || TypeError が発生 (コピー不可)&lt;br /&gt;
|-&lt;br /&gt;
| undefined || 削除される || 正常にコピー&lt;br /&gt;
|-&lt;br /&gt;
| Symbol || 削除される || TypeError が発生 (コピー不可)&lt;br /&gt;
|-&lt;br /&gt;
| BigInt || TypeError が発生 || 正常にコピー&lt;br /&gt;
|-&lt;br /&gt;
| 循環参照 || TypeError が発生 || 正常に処理&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;structuredClone()&amp;lt;/code&amp;gt; の使用例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 const original = {&lt;br /&gt;
    name: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    createdAt: new Date(&amp;quot;2024-01-15&amp;quot;),&lt;br /&gt;
    tags: new Set([&amp;quot;js&amp;quot;, &amp;quot;web&amp;quot;]),&lt;br /&gt;
    metadata: new Map([[&amp;quot;version&amp;quot;, &amp;quot;1.0&amp;quot;]])&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // structuredClone()でコピーする&lt;br /&gt;
 const copy = structuredClone(original);&lt;br /&gt;
 &lt;br /&gt;
 console.log(copy.createdAt instanceof Date);      // true (Dateが保持される)&lt;br /&gt;
 console.log(copy.tags instanceof Set);            // true (Setが保持される)&lt;br /&gt;
 console.log(copy.metadata instanceof Map);        // true (Mapが保持される)&lt;br /&gt;
 &lt;br /&gt;
 // 循環参照も正しくコピーできる&lt;br /&gt;
 const circular = { name: &amp;quot;test&amp;quot; };&lt;br /&gt;
 circular.self = circular;&lt;br /&gt;
 &lt;br /&gt;
 const circularCopy = structuredClone(circular);&lt;br /&gt;
 console.log(circularCopy.self === circularCopy);  // true (循環参照が維持される)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TauriでのJSON活用 ==&lt;br /&gt;
Tauri v2では、JavaScriptフロントエンドとRustバックエンド間のIPC通信において、JSON形式でデータが受け渡される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; 関数の引数と戻り値は自動的にシリアライズ・デシリアライズされる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
データフローを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
* JavaScript側 --&amp;gt; &amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; (自動) --&amp;gt; IPC通信&lt;br /&gt;
* IPC通信 --&amp;gt; &amp;lt;code&amp;gt;serde_json&amp;lt;/code&amp;gt; (自動) --&amp;gt; Rust構造体&lt;br /&gt;
* Rust構造体 --&amp;gt; &amp;lt;code&amp;gt;serde_json&amp;lt;/code&amp;gt; (自動) --&amp;gt; IPC通信&lt;br /&gt;
* IPC通信 --&amp;gt; &amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt; (自動) --&amp;gt; JavaScript側&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== invoke()によるデータ受け渡し ====&lt;br /&gt;
&amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; はJavaScriptからRustのコマンドを呼び出す関数であり、常にPromiseを返す。&amp;lt;br&amp;gt;&lt;br /&gt;
引数はオブジェクト形式で渡し、Rust側のコマンドのパラメータ名と一致させる必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // 文字列を送受信する基本的な例&lt;br /&gt;
 const result = await invoke(&amp;#039;my_command&amp;#039;, { message: &amp;#039;Hello, Tauri!&amp;#039; });&lt;br /&gt;
 console.log(result);  // Rust側から返ってきた文字列&lt;br /&gt;
 &lt;br /&gt;
 // オブジェクトを送受信する例&lt;br /&gt;
 const userData = {&lt;br /&gt;
    firstName: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    lastName: &amp;quot;Smith&amp;quot;,&lt;br /&gt;
    isPremium: true&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 const response = await invoke(&amp;#039;process_user&amp;#039;, { user: userData });&lt;br /&gt;
 console.log(response);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
対応するRust側のコマンド定義を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn my_command(message: String) -&amp;gt; String {&lt;br /&gt;
    format!(&amp;quot;受信: {}&amp;quot;, message)&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Rustの構造体とJSONの対応 ====&lt;br /&gt;
RustでJSONとの相互変換を行うには、&amp;lt;code&amp;gt;serde&amp;lt;/code&amp;gt; クレート と &amp;lt;code&amp;gt;serde_json&amp;lt;/code&amp;gt; クレートを使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;#[derive(Serialize, Deserialize)]&amp;lt;/code&amp;gt; アトリビュートを付与することにより、構造体の自動変換が有効になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
JavaScriptではキャメルケース、Rustではスネークケースが慣習となっているため、&amp;lt;code&amp;gt;#[serde(rename_all = &amp;quot;camelCase&amp;quot;)]&amp;lt;/code&amp;gt; アトリビュートを使用してフィールド名の変換ルールを設定することが推奨される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::{Serialize, Deserialize};&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Serialize, Deserialize)]&lt;br /&gt;
 #[serde(rename_all = &amp;quot;camelCase&amp;quot;)]&lt;br /&gt;
 struct UserData {&lt;br /&gt;
    first_name: String,   // JSON上では: firstName&lt;br /&gt;
    last_name: String,    // JSON上では: lastName&lt;br /&gt;
    is_premium: bool      // JSON上では: isPremium&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn process_user(user: UserData) -&amp;gt; UserData {&lt;br /&gt;
    println!(&amp;quot;名前: {} {}&amp;quot;, user.first_name, user.last_name);&lt;br /&gt;
    user  // そのまま返す&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
JavaScript側から以下に示すように呼び出す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // camelCaseのキーでオブジェクトを送る&lt;br /&gt;
 const result = await invoke(&amp;#039;process_user&amp;#039;, {&lt;br /&gt;
    user: {&lt;br /&gt;
       firstName: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
       lastName: &amp;quot;Smith&amp;quot;,&lt;br /&gt;
       isPremium: true&lt;br /&gt;
    }&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 // 戻り値もcamelCaseで受け取る&lt;br /&gt;
 console.log(result.firstName);  // &amp;quot;Alice&amp;quot;&lt;br /&gt;
 console.log(result.isPremium);  // true&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複雑なデータ構造の受け渡し ====&lt;br /&gt;
Rustの主要なデータ型とJSONの対応を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
===== Vec&amp;lt;T&amp;gt; (配列) =====&lt;br /&gt;
Rustの &amp;lt;code&amp;gt;Vec&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; はJSONの配列として受け渡される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::{Serialize, Deserialize};&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Serialize, Deserialize)]&lt;br /&gt;
 struct Item {&lt;br /&gt;
    id: u32,&lt;br /&gt;
    name: String&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn process_items(items: Vec&amp;lt;Item&amp;gt;) -&amp;gt; u32 {&lt;br /&gt;
    items.len() as u32&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const count = await invoke(&amp;#039;process_items&amp;#039;, {&lt;br /&gt;
    items: [&lt;br /&gt;
       { id: 1, name: &amp;quot;Item A&amp;quot; },&lt;br /&gt;
       { id: 2, name: &amp;quot;Item B&amp;quot; }&lt;br /&gt;
    ]&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 console.log(count);  // 2&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
===== Option&amp;lt;T&amp;gt; (null許容値) =====&lt;br /&gt;
Rustの &amp;lt;code&amp;gt;Option&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; は、&amp;lt;code&amp;gt;Some(value)&amp;lt;/code&amp;gt; が値そのものに、&amp;lt;code&amp;gt;None&amp;lt;/code&amp;gt; が &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; にマッピングされる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::{Serialize, Deserialize};&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Serialize, Deserialize)]&lt;br /&gt;
 #[serde(rename_all = &amp;quot;camelCase&amp;quot;)]&lt;br /&gt;
 struct Profile {&lt;br /&gt;
    name: String,&lt;br /&gt;
    middle_name: Option&amp;lt;String&amp;gt;  // null の可能性あり&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn get_profile(has_middle: bool) -&amp;gt; Profile {&lt;br /&gt;
    Profile {&lt;br /&gt;
       name: &amp;quot;Alice&amp;quot;.to_string(),&lt;br /&gt;
       middle_name: if has_middle { Some(&amp;quot;Marie&amp;quot;.to_string()) } else { None }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 const profile1 = await invoke(&amp;#039;get_profile&amp;#039;, { hasMiddle: true });&lt;br /&gt;
 console.log(profile1.middleName);  // &amp;quot;Marie&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 const profile2 = await invoke(&amp;#039;get_profile&amp;#039;, { hasMiddle: false });&lt;br /&gt;
 console.log(profile2.middleName);  // null&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
===== Enum (列挙型) =====&lt;br /&gt;
Rustの列挙型は &amp;lt;code&amp;gt;#[serde(tag = &amp;quot;type&amp;quot;)]&amp;lt;/code&amp;gt; アトリビュートを使用することで、JavaScriptのオブジェクトにマッピングできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::{Serialize, Deserialize};&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Serialize, Deserialize)]&lt;br /&gt;
 #[serde(tag = &amp;quot;type&amp;quot;)]&lt;br /&gt;
 enum RequestType {&lt;br /&gt;
    Create { name: String },&lt;br /&gt;
    Update { id: u32, name: String },&lt;br /&gt;
    Delete { id: u32 }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn handle_request(request: RequestType) -&amp;gt; String {&lt;br /&gt;
    match request {&lt;br /&gt;
       RequestType::Create { name } =&amp;gt; format!(&amp;quot;作成: {}&amp;quot;, name),&lt;br /&gt;
       RequestType::Update { id, name } =&amp;gt; format!(&amp;quot;更新: id={}, name={}&amp;quot;, id, name),&lt;br /&gt;
       RequestType::Delete { id } =&amp;gt; format!(&amp;quot;削除: id={}&amp;quot;, id)&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 // Createリクエスト&lt;br /&gt;
 const res1 = await invoke(&amp;#039;handle_request&amp;#039;, {&lt;br /&gt;
    request: { type: &amp;#039;Create&amp;#039;, name: &amp;#039;New Item&amp;#039; }&lt;br /&gt;
 });&lt;br /&gt;
 console.log(res1);  // &amp;quot;作成: New Item&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Updateリクエスト&lt;br /&gt;
 const res2 = await invoke(&amp;#039;handle_request&amp;#039;, {&lt;br /&gt;
    request: { type: &amp;#039;Update&amp;#039;, id: 42, name: &amp;#039;Updated Item&amp;#039; }&lt;br /&gt;
 });&lt;br /&gt;
 console.log(res2);  // &amp;quot;更新: id=42, name=Updated Item&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Deleteリクエスト&lt;br /&gt;
 const res3 = await invoke(&amp;#039;handle_request&amp;#039;, {&lt;br /&gt;
    request: { type: &amp;#039;Delete&amp;#039;, id: 42 }&lt;br /&gt;
 });&lt;br /&gt;
 console.log(res3);  // &amp;quot;削除: id=42&amp;quot;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連情報 ==&lt;br /&gt;
* [[JavaScriptの基礎 - Fetch API]]&lt;br /&gt;
*: Promiseを返すFetch APIによるHTTPリクエストの定義&lt;br /&gt;
* [[JavaScriptの基礎 - Promise]]&lt;br /&gt;
*: Promiseの基本構文から静的メソッド、Tauriでの使用例&lt;br /&gt;
* [[JavaScriptの基礎 - async await]]&lt;br /&gt;
*: Promiseをより簡潔に記述するためのasync / await構文の詳細&lt;br /&gt;
* [[JavaScriptの基礎 - エラーハンドリング]]&lt;br /&gt;
*: try / catch、カスタムエラー、エラーの伝播&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:Web]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>