diff options
Diffstat (limited to 'files/zh-tw/web/javascript/reference/global_objects/json')
3 files changed, 656 insertions, 0 deletions
diff --git a/files/zh-tw/web/javascript/reference/global_objects/json/index.html b/files/zh-tw/web/javascript/reference/global_objects/json/index.html new file mode 100644 index 0000000000..8d3aeadbf2 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/json/index.html @@ -0,0 +1,206 @@ +--- +title: JSON +slug: Web/JavaScript/Reference/Global_Objects/JSON +tags: + - JSON + - JavaScript + - NeedsTranslation + - Object + - Reference + - Référence(2) + - TopicStub + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/JSON +--- +<div>{{JSRef}}</div> + +<p><strong><code>JSON</code></strong> 物件包含了解析、或是轉換為 <a class="external" href="http://json.org/">JavaScript Object Notation</a>({{glossary("JSON")}})格式的方法。這物件不能被呼叫或建構;而除了它的兩個方法屬性以外,本身也沒有特別的功能。</p> + +<h2 id="描述">描述</h2> + +<h3 id="JavaScript_Object_Notation">JavaScript Object Notation</h3> + +<p>JSON 是序列物件、陣列、數字、字串、布林值、還有 {{jsxref("null")}} 的語法。它建基、但不同於 JavaScript:有些 JavaScript 不是 JSON、而有些 JSON 不是 JavaScript。請參見 <a href="http://timelessrepo.com/json-isnt-a-javascript-subset">JSON: The JavaScript subset that isn't</a>。</p> + +<table> + <caption>JavaScript 與 JSON 的差別</caption> + <thead> + <tr> + <th scope="col">JavaScript 型別</th> + <th scope="col">與 JSON 的差別</th> + </tr> + </thead> + <tbody> + <tr> + <td>物件與陣列</td> + <td>屬性名稱必須是包含在雙引號中的字串;禁止尾後逗號。</td> + </tr> + <tr> + <td>數字</td> + <td>數字不可以0作為開頭(在 JSON.stringify 0會被忽略,但是在 JSON.parse 會造成語法錯誤);小數點前面必須至少有一位數字。</td> + </tr> + <tr> + <td>字串</td> + <td> + <p>Only a limited set of characters may be escaped; certain control characters are prohibited; the Unicode line separator (<a href="http://unicode-table.com/en/2028/">U+2028</a>) and paragraph separator (<a href="http://unicode-table.com/en/2029/">U+2029</a>) characters are permitted; strings must be double-quoted. See the following example where {{jsxref("JSON.parse()")}} works fine and a {{jsxref("SyntaxError")}} is thrown when evaluating the code as JavaScript:</p> + + <pre class="brush: js"> +var code = '"\u2028\u2029"'; +JSON.parse(code); // works fine +eval(code); // fails +</pre> + </td> + </tr> + </tbody> +</table> + +<p>JSON 的完整語法如下:</p> + +<pre><var>JSON</var> = <strong>null</strong> + <em>or</em> <strong>true</strong> <em>or</em> <strong>false</strong> + <em>or</em> <var>JSONNumber</var> + <em>or</em> <var>JSONString</var> + <em>or</em> <var>JSONObject</var> + <em>or</em> <var>JSONArray</var> + +<var>JSONNumber</var> = <strong>-</strong> <var>PositiveNumber</var> + <em>or</em> <var>PositiveNumber</var> +<var>PositiveNumber</var> = DecimalNumber + <em>or</em> <var>DecimalNumber</var> <strong>.</strong> <var>Digits</var> + <em>or</em> <var>DecimalNumber</var> <strong>.</strong> <var>Digits</var> <var>ExponentPart</var> + <em>or</em> <var>DecimalNumber</var> <var>ExponentPart</var> +<var>DecimalNumber</var> = <strong>0</strong> + <em>or</em> <var>OneToNine</var> <var>Digits</var> +<var>ExponentPart</var> = <strong>e</strong> <var>Exponent</var> + <em>or</em> <strong>E</strong> <var>Exponent</var> +<var>Exponent</var> = <var>Digits</var> + <em>or</em> <strong>+</strong> <var>Digits</var> + <em>or</em> <strong>-</strong> <var>Digits</var> +<var>Digits</var> = <var>Digit</var> + <em>or</em> <var>Digits</var> <var>Digit</var> +<var>Digit</var> = <strong>0</strong> through <strong>9</strong> +<var>OneToNine</var> = <strong>1</strong> through <strong>9</strong> + +<var>JSONString</var> = <strong>""</strong> + <em>or</em> <strong>"</strong> <var>StringCharacters</var> <strong>"</strong> +<var>StringCharacters</var> = <var>StringCharacter</var> + <em>or</em> <var>StringCharacters</var> <var>StringCharacter</var> +<var>StringCharacter</var> = any character + <em>except</em> <strong>"</strong> <em>or</em> <strong>\</strong> <em>or</em> U+0000 through U+001F + <em>or</em> <var>EscapeSequence</var> +<var>EscapeSequence</var> = <strong>\"</strong> <em>or</em> <strong>\/</strong> <em>or</em> <strong>\\</strong> <em>or</em> <strong>\b</strong> <em>or</em> <strong>\f</strong> <em>or</em> <strong>\n</strong> <em>or</em> <strong>\r</strong> <em>or</em> <strong>\t</strong> + <em>or</em> <strong>\u</strong> <var>HexDigit</var> <var>HexDigit</var> <var>HexDigit</var> <var>HexDigit</var> +<var>HexDigit</var> = <strong>0</strong> through <strong>9</strong> + <em>or</em> <strong>A</strong> through <strong>F</strong> + <em>or</em> <strong>a</strong> through <strong>f</strong> + +<var>JSONObject</var> = <strong>{</strong> <strong>}</strong> + <em>or</em> <strong>{</strong> <var>Members</var> <strong>}</strong> +<var>Members</var> = <var>JSONString</var> <strong>:</strong> <var>JSON</var> + <em>or</em> <var>Members</var> <strong>,</strong> <var>JSONString</var> <strong>:</strong> <var>JSON</var> + +<var>JSONArray</var> = <strong>[</strong> <strong>]</strong> + <em>or</em> <strong>[</strong> <var>ArrayElements</var> <strong>]</strong> +<var>ArrayElements</var> = <var>JSON</var> + <em>or</em> <var>ArrayElements</var> <strong>,</strong> <var>JSON</var> +</pre> + +<p>Insignificant whitespace may be present anywhere except within a <code><var>JSONNumber</var></code> (numbers must contain no whitespace) or <code><var>JSONString</var></code> (where it is interpreted as the corresponding character in the string, or would cause an error). The tab character (<a href="http://unicode-table.com/en/0009/">U+0009</a>), carriage return (<a href="http://unicode-table.com/en/000D/">U+000D</a>), line feed (<a href="http://unicode-table.com/en/000A/">U+000A</a>), and space (<a href="http://unicode-table.com/en/0020/">U+0020</a>) characters are the only valid whitespace characters.</p> + +<h2 id="方法">方法</h2> + +<dl> + <dt>{{jsxref("JSON.parse()")}}</dt> + <dd>解析 JSON 字串,能改變給定值和屬性、接著回傳解析值。</dd> + <dt>{{jsxref("JSON.stringify()")}}</dt> + <dd>回傳給定的 JSON 對應字串,可自行決定只想包括哪些特定屬性、或替換的屬性值。</dd> +</dl> + +<h2 id="Polyfill">Polyfill</h2> + +<p>舊版瀏覽器並不支援 <code>JSON</code>。你可以在程式碼開頭插入以下程式碼,以解決這個問題。這個程式碼能實做不支援原生 <code>JSON</code> 物件的瀏覽器(如 Internet Explorer 6)。</p> + +<p>以下演算法能仿製原生 <code>JSON</code> 物件。</p> + +<pre class="brush: js">if (!window.JSON) { + window.JSON = { + parse: function(sJSON) { return eval('(' + sJSON + ')'); }, + stringify: (function () { + var toString = Object.prototype.toString; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; }; + var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'}; + var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); }; + var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g; + return function stringify(value) { + if (value == null) { + return 'null'; + } else if (typeof value === 'number') { + return isFinite(value) ? value.toString() : 'null'; + } else if (typeof value === 'boolean') { + return value.toString(); + } else if (typeof value === 'object') { + if (typeof value.toJSON === 'function') { + return stringify(value.toJSON()); + } else if (isArray(value)) { + var res = '['; + for (var i = 0; i < value.length; i++) + res += (i ? ', ' : '') + stringify(value[i]); + return res + ']'; + } else if (toString.call(value) === '[object Object]') { + var tmp = []; + for (var k in value) { + // in case "hasOwnProperty" has been shadowed + if (hasOwnProperty.call(value, k)) + tmp.push(stringify(k) + ': ' + stringify(value[k])); + } + return '{' + tmp.join(', ') + '}'; + } + } + return '"' + value.toString().replace(escRE, escFunc) + '"'; + }; + })() + }; +} +</pre> + +<p>More complex well-known <a class="external" href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">polyfills</a> for the <code>JSON</code> object are <a class="link-https" href="https://github.com/douglascrockford/JSON-js">JSON2</a> and <a class="external" href="http://bestiejs.github.com/json3">JSON3</a>.</p> + +<h2 id="規範">規範</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.12', 'JSON')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-json-object', 'JSON')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-json-object', 'JSON')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="瀏覽器相容性">瀏覽器相容性</h2> + + + +<div>{{Compat("javascript.builtins.JSON")}}</div> + +<h2 id="參見">參見</h2> + +<ul> + <li>{{jsxref("Date.prototype.toJSON()")}}</li> +</ul> diff --git a/files/zh-tw/web/javascript/reference/global_objects/json/parse/index.html b/files/zh-tw/web/javascript/reference/global_objects/json/parse/index.html new file mode 100644 index 0000000000..eb821587a5 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/json/parse/index.html @@ -0,0 +1,170 @@ +--- +title: JSON.parse() +slug: Web/JavaScript/Reference/Global_Objects/JSON/parse +translation_of: Web/JavaScript/Reference/Global_Objects/JSON/parse +--- +<div>{{JSRef}}</div> + +<p><strong><code>JSON.parse()</code></strong> 方法把會把一個JSON字串轉換成 JavaScript的數值或是物件。另外也可選擇使用reviver函數讓這些數值或是物件在被回傳之前做轉換。</p> + +<h2 id="語法">語法</h2> + +<pre class="syntaxbox">JSON.parse(<var>text</var>[, <var>reviver</var>])</pre> + +<h3 id="參數">參數</h3> + +<dl> + <dt><code>text</code></dt> + <dd>要解析成 JSON 的字串。針對 JSON 語法的描述,請參見 {{jsxref("JSON")}} 物件。</dd> + <dt><code>reviver</code> {{optional_inline}}</dt> + <dd>為選擇性的參數,用來描述JSON字串中的值該如何被解析並回傳的函式(function)</dd> +</dl> + +<h3 id="回傳值">回傳值</h3> + +<p>從給定的 JSON <code>text</code> 回傳對應的 {{jsxref("Object")}}。</p> + +<h3 id="Throws">Throws</h3> + +<p>如果解析的字串不是合法的JSON格式會丟出一個 {{jsxref("SyntaxError")}} 例外</p> + +<h2 id="範例">範例</h2> + +<h3 id="Using_JSON.parse">Using <code>JSON.parse()</code></h3> + +<pre class="brush: js">JSON.parse('{}'); // {} +JSON.parse('true'); // true +JSON.parse('"foo"'); // "foo" +JSON.parse('[1, 5, "false"]'); // [1, 5, "false"] +JSON.parse('null'); // null +</pre> + +<h3 id="使用_reviver_參數">使用 <strong><code>reviver</code></strong> 參數</h3> + +<p><code><font face="Open Sans, Arial, sans-serif">如果</font>reviver函數有被指定</code>,字串解析後產生出來的值會在函式回傳前經過轉換。 具體來講,解析後的值或是物件屬性會一個接一個地被這個reviver函數過濾(順序是由巢狀架構中最深的到最淺的),而當一個屬性即將被過濾時,該屬性的名稱(字串形態)以及值會被當作參數傳入reviver函數。如果reviver函數回傳了 {{jsxref("undefined")}} (或是沒有回傳值, 例如:函式提早結束),則該屬性會從物件中被刪除;反之如果成功的話,該屬性的值就會被新的回傳值取代。</p> + +<p>如果reviver只需轉換某些特定的值,請記得將其他不須特別轉換的值以原來的值回傳,否則這些值會從回傳的結果物件中刪除。</p> + +<pre class="brush: js">JSON.parse('{"p": 5}', function(k, v) { + if (typeof v === 'number') { + return v * 2; // return v * 2 for numbers + } + return v; // return everything else unchanged +}); + +// { p: 10 } + +JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', function(k, v) { + console.log(k); // log the current property name, the last is "". + return v; // return the unchanged property value. +}); + +// 1 +// 2 +// 4 +// 6 +// 5 +// 3 +// "" +</pre> + +<h3 id="JSON.parse_不容許尾部有逗號"><code>JSON.parse()</code> 不容許尾部有逗號</h3> + +<pre class="example-bad brush: js example-bad">// 這兩個都會拋出 SyntaxError +JSON.parse('[1, 2, 3, 4, ]'); +JSON.parse('{"foo" : 1, }'); +</pre> + +<h2 id="規範">規範</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">規範</th> + <th scope="col">狀態</th> + <th scope="col">註解</th> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.12.2', 'JSON.parse')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>初始定義。從 JavaScript 1.7 導入。</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-json.parse', 'JSON.parse')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-json.parse', 'JSON.parse')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="瀏覽器相容性">瀏覽器相容性</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>特徵</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>基本功能</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("1.9.1")}}</td> + <td>{{CompatIE("8.0")}}</td> + <td>{{CompatOpera("10.5")}}</td> + <td>{{CompatSafari("4.0")}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>特徵</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>基本功能</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("1.0")}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Gecko相關">Gecko相關</h2> + +<p>從Gecko 29版本開始{{geckoRelease("29")}},錯誤格式的JSON字串會產生更詳細的錯誤訊息,包含造成解析錯誤的行數及列數。這在針對大量JSON資料進行除錯時會很有幫助。</p> + +<pre class="brush: js">JSON.parse('[1, 2, 3, 4,]'); +// SyntaxError: JSON.parse: unexpected character at +// line 1 column 13 of the JSON data +</pre> + +<h2 id="參見">參見</h2> + +<ul> + <li>{{jsxref("JSON.stringify()")}}</li> +</ul> diff --git a/files/zh-tw/web/javascript/reference/global_objects/json/stringify/index.html b/files/zh-tw/web/javascript/reference/global_objects/json/stringify/index.html new file mode 100644 index 0000000000..5169d7d748 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/global_objects/json/stringify/index.html @@ -0,0 +1,280 @@ +--- +title: JSON.stringify() +slug: Web/JavaScript/Reference/Global_Objects/JSON/stringify +translation_of: Web/JavaScript/Reference/Global_Objects/JSON/stringify +--- +<div>{{JSRef}}</div> + +<p><strong><code>JSON.stringify()</code></strong> method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified.</p> + +<div>{{EmbedInteractiveExample("pages/js/json-stringify.html")}}</div> + +<h2 id="語法">語法</h2> + +<pre class="syntaxbox"><code>JSON.stringify(<var>value</var>[, <var>replacer</var>[, <var>space</var>]])</code></pre> + +<h3 id="參數">參數</h3> + +<dl> + <dt><code>value</code></dt> + <dd>The value to convert to a JSON string.</dd> + <dt><code>replacer</code> {{optional_inline}}</dt> + <dd>A function that alters the behavior of the stringification process, or an array of {{jsxref("String")}} and {{jsxref("Number")}} objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string.</dd> + <dt><code>space</code> {{optional_inline}}</dt> + <dd>A {{jsxref("String")}} or {{jsxref("Number")}} object that's used to insert white space into the output JSON string for readability purposes. If this is a <code>Number</code>, it indicates the number of space characters to use as white space; this number is capped at 10 (if it is greater, the value is just 10). Values less than 1 indicate that no space should be used. If this is a <code>String</code>, the string (or the first 10 characters of the string, if it's longer than that) is used as white space. If this parameter is not provided (or is null), no white space is used.</dd> +</dl> + +<h3 id="回傳值">回傳值</h3> + +<p>A JSON string representing the given value.</p> + +<h2 id="Description">Description</h2> + +<p><code>JSON.stringify()</code> converts a value to JSON notation representing it:</p> + +<ul> + <li>{{jsxref("Boolean")}}, {{jsxref("Number")}}, and {{jsxref("String")}} objects are converted to the corresponding primitive values during stringification, in accord with the traditional conversion semantics.</li> + <li>If {{jsxref("undefined")}}, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to {{jsxref("null")}} (when it is found in an array). <code>JSON.stringify</code> can also just return <code>undefined</code> when passing in "pure" values like <code>JSON.stringify(function(){})</code> or <code>JSON.stringify(undefined)</code>.</li> + <li>All symbol-keyed properties will be completely ignored, even when using the <code>replacer</code> function.</li> + <li>Non-enumerable properties will be ignored</li> +</ul> + +<pre class="brush: js">JSON.stringify({}); // '{}' +JSON.stringify(true); // 'true' +JSON.stringify('foo'); // '"foo"' +JSON.stringify([1, 'false', false]); // '[1,"false",false]' +JSON.stringify({ x: 5 }); // '{"x":5}' + +JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)) +// '"2006-01-02T15:04:05.000Z"' + +JSON.stringify({ x: 5, y: 6 }); +// '{"x":5,"y":6}' +JSON.stringify([new Number(3), new String('false'), new Boolean(false)]); +// '[3,"false",false]' + +JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }); +// '{"x":[10,null,null,null]}' + +// Symbols: +JSON.stringify({ x: undefined, y: Object, z: Symbol('') }); +// '{}' +JSON.stringify({ [Symbol('foo')]: 'foo' }); +// '{}' +JSON.stringify({ [Symbol.for('foo')]: 'foo' }, [Symbol.for('foo')]); +// '{}' +JSON.stringify({ [Symbol.for('foo')]: 'foo' }, function(k, v) { + if (typeof k === 'symbol') { + return 'a symbol'; + } +}); +// '{}' + +// Non-enumerable properties: +JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) ); +// '{"y":"y"}' + +</pre> + +<h3 id="The_replacer_parameter"><a id="The replacer parameter" name="The replacer parameter"></a>The <code>replacer</code> parameter</h3> + +<p>The <code>replacer</code> parameter can be either a function or an array. As a function, it takes two parameters, the key and the value being stringified. The object in which the key was found is provided as the replacer's <code>this</code> parameter. Initially it gets called with an empty key representing the object being stringified, and it then gets called for each property on the object or array being stringified. It should return the value that should be added to the JSON string, as follows:</p> + +<ul> + <li>If you return a {{jsxref("Number")}}, the string corresponding to that number is used as the value for the property when added to the JSON string.</li> + <li>If you return a {{jsxref("String")}}, that string is used as the property's value when adding it to the JSON string.</li> + <li>If you return a {{jsxref("Boolean")}}, "true" or "false" is used as the property's value, as appropriate, when adding it to the JSON string.</li> + <li>If you return any other object, the object is recursively stringified into the JSON string, calling the <code>replacer</code> function on each property, unless the object is a function, in which case nothing is added to the JSON string.</li> + <li>If you return <code>undefined</code>, the property is not included (i.e., filtered out) in the output JSON string.</li> +</ul> + +<div class="note"><strong>Note:</strong> You cannot use the <code>replacer</code> function to remove values from an array. If you return <code>undefined</code> or a function then <code>null</code> is used instead.</div> + +<h4 id="Example_with_a_function">Example with a function</h4> + +<pre class="brush: js">function replacer(key, value) { + // Filtering out properties + if (typeof value === 'string') { + return undefined; + } + return value; +} + +var foo = {foundation: 'Mozilla', model: 'box', week: 45, transport: 'car', month: 7}; +JSON.stringify(foo, replacer); +// '{"week":45,"month":7}' +</pre> + +<h4 id="Example_with_an_array">Example with an array</h4> + +<p>If <code>replacer</code> is an array, the array's values indicate the names of the properties in the object that should be included in the resulting JSON string.</p> + +<pre class="brush: js">JSON.stringify(foo, ['week', 'month']); +// '{"week":45,"month":7}', only keep "week" and "month" properties +</pre> + +<h3 id="The_space_argument"><a id="The space argument" name="The space argument"></a>The <code>space</code> argument</h3> + +<p>The <code>space</code> argument may be used to control spacing in the final string. If it is a number, successive levels in the stringification will each be indented by this many space characters (up to 10). If it is a string, successive levels will be indented by this string (or the first ten characters of it).</p> + +<pre class="brush: js">JSON.stringify({ a: 2 }, null, ' '); +// '{ +// "a": 2 +// }' +</pre> + +<p>Using a tab character mimics standard pretty-print appearance:</p> + +<pre class="brush: js">JSON.stringify({ uno: 1, dos: 2 }, null, '\t'); +// returns the string: +// '{ +// "uno": 1, +// "dos": 2 +// }' +</pre> + +<h3 id="toJSON_behavior"><code>toJSON()</code> behavior</h3> + +<p>If an object being stringified has a property named <code>toJSON</code> whose value is a function, then the <code>toJSON()</code> method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the <code>toJSON()</code> method when called will be serialized. <code>JSON.stringify()</code> calls <code>toJSON</code> with one parameter:</p> + +<ul> + <li>if this object is a property value, the property name</li> + <li>if it is in an array, the index in the array, as a string</li> + <li>an empty string if <code>JSON.stringify()</code> was directly called on this object</li> +</ul> + +<p>For example:</p> + +<pre class="brush: js">const bonnie = { + name: 'Bonnie Washington', + age: 17, + class: 'Year 5 Wisdom', + isMonitor: false, + toJSON: function(key) { + // Clone object to prevent accidentally performing modification on the original object + const cloneObj = { ...this }; + + delete cloneObj.age; + delete cloneObj.isMonitor; + cloneObj.year = 5; + cloneObj.class = 'Wisdom'; + + if (key) { + cloneObj.code = key; + } + + return cloneObj; + } +} + +JSON.stringify(bonnie); +// Returns '{"name":"Bonnie Washington","class":"Wisdom","year":5}' + +const students = {bonnie}; +JSON.stringify(students); +// Returns '{"bonnie":{"name":"Bonnie Washington","class":"Wisdom","year":5,"code":"bonnie"}}' + +const monitorCandidate = [bonnie]; +JSON.stringify(monitorCandidate) +// Returns '[{"name":"Bonnie Washington","class":"Wisdom","year":5,"code":"0"}]'</pre> + +<h3 id="Issue_with_plain_JSON.stringify_for_use_as_JavaScript">Issue with plain <code>JSON.stringify</code> for use as JavaScript</h3> + +<p>Note that JSON is <a href="http://timelessrepo.com/json-isnt-a-javascript-subset">not a completely strict subset of JavaScript</a>, with two line terminators (Line separator and Paragraph separator) not needing to be escaped in JSON but needing to be escaped in JavaScript. Therefore, if the JSON is meant to be evaluated or directly utilized within <a href="https://en.wikipedia.org/wiki/JSONP">JSONP</a>, the following utility can be used:</p> + +<pre class="brush: js">function jsFriendlyJSONStringify (s) { + return JSON.stringify(s). + replace(/\u2028/g, '\\u2028'). + replace(/\u2029/g, '\\u2029'); +} + +var s = { + a: String.fromCharCode(0x2028), + b: String.fromCharCode(0x2029) +}; +try { + eval('(' + JSON.stringify(s) + ')'); +} catch (e) { + console.log(e); // "SyntaxError: unterminated string literal" +} + +// No need for a catch +eval('(' + jsFriendlyJSONStringify(s) + ')'); + +// console.log in Firefox unescapes the Unicode if +// logged to console, so we use alert +alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}</pre> + +<h3 id="Example_of_using_JSON.stringify_with_localStorage">Example of using <code>JSON.stringify()</code> with <code>localStorage</code></h3> + +<p>In a case where you want to store an object created by your user and allowing it to be restored even after the browser has been closed, the following example is a model for the applicability of <code>JSON.stringify()</code>:</p> + +<div class="warning"> +<p>Functions are not a valid JSON data type so they will not work. However, they can be displayed if first converted to a string (e.g. in the replacer), via the function's toString method. Also, some objects like {{jsxref("Date")}} will be a string after {{jsxref("JSON.parse()")}}.</p> +</div> + +<pre class="brush: js">// Creating an example of JSON +var session = { + 'screens': [], + 'state': true +}; +session.screens.push({ 'name': 'screenA', 'width': 450, 'height': 250 }); +session.screens.push({ 'name': 'screenB', 'width': 650, 'height': 350 }); +session.screens.push({ 'name': 'screenC', 'width': 750, 'height': 120 }); +session.screens.push({ 'name': 'screenD', 'width': 250, 'height': 60 }); +session.screens.push({ 'name': 'screenE', 'width': 390, 'height': 120 }); +session.screens.push({ 'name': 'screenF', 'width': 1240, 'height': 650 }); + +// Converting the JSON string with JSON.stringify() +// then saving with localStorage in the name of session +localStorage.setItem('session', JSON.stringify(session)); + +// Example of how to transform the String generated through +// JSON.stringify() and saved in localStorage in JSON object again +var restoredSession = JSON.parse(localStorage.getItem('session')); + +// Now restoredSession variable contains the object that was saved +// in localStorage +console.log(restoredSession); +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.12.3', 'JSON.stringify')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.7.</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-json.stringify', 'JSON.stringify')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-json.stringify', 'JSON.stringify')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div> + + +<p>{{Compat("javascript.builtins.JSON.stringify")}}</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("JSON.parse()")}}</li> +</ul> |