mozilla

Revision 640779 of JSON.stringify()

  • Revision slug: Web/JavaScript/Reference/Global_Objects/JSON/stringify
  • Revision title: stringify
  • Revision id: 640779
  • Created:
  • Creator: ziyunfei
  • Is current revision? No
  • Comment

Revision Content

{{JSRef("Global_Objects", "JSON")}}

概述

JSON.stringify() 方法可以将任意的 JavaScript 值序列化成 JSON 字符串。

语法

JSON.stringify(value[, replacer [, space]])

参数

value
将要序列化成 JSON 字符串的值。
replacer {{optional_inline}}
如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中。关于该参数更详细的解释和示例,请参考使用原生的 JSON 对象一文。
space {{optional_inline}}
指定缩进用的空白字符串,用于美化输出(pretty-print)。

描述

关于序列化,有下面三点注意事项:

  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
  • undefined、任意的函数值以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。
  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
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({x: 5, y: 6});              
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); 
// '[1,"false",false]'
JSON.stringify({x: undefined, y: Object, z: Symbol("")}); 
// '{}'
JSON.stringify([undefined, Object, Symbol("")]);          
// '[null,null,null]' 
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";
  }
});
// '{}'

space 参数

space 参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进用该字符串(或该字符串的前十个字符)。

JSON.stringify({ a: 2 }, null, " ");   // '{\n "a": 2\n}'

使用制表符(\t)来缩进:

JSON.stringify({ uno: 1, dos : 2 }, null, '\t')
// '{            \
//     "uno": 1, \
//     "dos": 2  \
// }' 

toJSON 方法

如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 toJSON 方法后的返回值会被序列化,例如:

var obj = {
  foo: 'foo',
  toJSON: function () {
    return 'bar';
  }
};
JSON.stringify(obj);      // '"bar"'
JSON.stringify({x: obj}); // '{"x":"bar"}'

使用 JSON.stringify 结合 localStorage 的例子

一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象。下面的例子是 JSON.stringify 适用于这种情形的一个样板:

// 创建一个示例数据
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});

// 使用 JSON.stringify 转换为 JSON 字符串
// 然后使用 localStorage 保存在 session 名称里
localStorage.setItem('session', JSON.stringify(session));

// 然后是如何转换通过 JSON.stringify 生成的字符串,该字符串以 JSON 格式保存在 localStorage 里
var restoredSession = JSON.parse(localStorage.getItem('session'));

// 现在 restoredSession 包含了保存在 localStorage 里的对象
console.log(restoredSession);

规范

规范名称及链接 规范状态
{{SpecName('ES5.1', '#sec-15.12.3', 'JSON.stringify')}} {{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-json.stringify', 'JSON.stringify')}} {{Spec2('ES6')}}

浏览器兼容性

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{ CompatVersionUnknown() }} {{ CompatGeckoDesktop("1.9.1") }} 8.0 10.5 4.0
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatVersionUnknown() }} {{ CompatVersionUnknown() }} {{ CompatGeckoMobile("1.0") }} {{ CompatVersionUnknown() }} {{ CompatVersionUnknown() }} {{ CompatVersionUnknown() }}

相关链接

Revision Source

<div>
 {{JSRef("Global_Objects", "JSON")}}</div>
<h2 id="Summary" name="Summary">概述</h2>
<p><code><strong>JSON.stringify()</strong></code> 方法可以将任意的 JavaScript 值序列化成 JSON 字符串。</p>
<h2 id="Syntax" name="Syntax">语法</h2>
<pre class="syntaxbox">
<code>JSON.stringify(<em>value</em>[, <em>replacer</em> [, <em>space</em>]])</code></pre>
<h3 id="Parameters" name="Parameters">参数</h3>
<dl>
 <dt>
  <code>value</code></dt>
 <dd>
  将要序列化成 JSON 字符串的值。</dd>
 <dt>
  <code>replacer</code> {{optional_inline}}</dt>
 <dd>
  如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中。关于该参数更详细的解释和示例,请参考<a href="/zh-CN/docs/Web/JavaScript/Guide/Using_native_JSON#The_replacer_parameter">使用原生的 JSON 对象</a>一文。</dd>
 <dt>
  <code>space</code> {{optional_inline}}</dt>
 <dd>
  指定缩进用的空白字符串,用于美化输出(pretty-print)。</dd>
</dl>
<h2 id=".E6.8F.8F.E8.BF.B0">描述</h2>
<p>关于序列化,有下面三点注意事项:</p>
<ul>
 <li>非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。</li>
 <li>布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。</li>
 <li><code>undefined、</code>任意的函数值以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 <code>null</code>(出现在数组中时)。</li>
 <li>所有以 symbol 为属性键的属性都会被完全忽略掉,即便 <code>replacer</code> 参数中强制指定包含了它们。</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({x: 5, y: 6});              
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); 
// '[1,"false",false]'
JSON.stringify({x: undefined, y: Object, z: Symbol("")}); 
// '{}'
JSON.stringify([undefined, Object, Symbol("")]);          
// '[null,null,null]' 
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";
  }
});
// '{}'
</pre>
<h3 id="space_.E5.8F.82.E6.95.B0"><code>space</code> 参数</h3>
<p>space 参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进用该字符串(或该字符串的前十个字符)。</p>
<pre class="brush: js">
JSON.stringify({ a: 2 }, null, " ");   // '{\n "a": 2\n}'</pre>
<p>使用制表符(\t)来缩进:</p>
<pre class="brush: js">
JSON.stringify({ uno: 1, dos : 2 }, null, '\t')
// '{            \
//     "uno": 1, \
//     "dos": 2  \
// }' 
</pre>
<h3 id="toJSON_.E6.96.B9.E6.B3.95">toJSON 方法</h3>
<p>如果一个被序列化的对象拥有 <code>toJSON</code> 方法,那么该 <code>toJSON</code> 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 <code>toJSON</code> 方法后的返回值会被序列化,例如:</p>
<pre class="brush: js">
var obj = {
  foo: 'foo',
  toJSON: function () {
    return 'bar';
  }
};
JSON.stringify(obj);      // <code>'"bar"'</code>
JSON.stringify({x: obj}); // <code>'{"x":"bar"}'</code>
</pre>
<h3 id=".E4.BD.BF.E7.94.A8_JSON.stringify_.E7.BB.93.E5.90.88_localStorage_.E7.9A.84.E4.BE.8B.E5.AD.90">使用 JSON.stringify 结合 localStorage 的例子</h3>
<p>一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象。下面的例子是 <code>JSON.stringify</code> 适用于这种情形的一个样板:</p>
<pre class="brush: js">
// 创建一个示例数据
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});

// 使用 JSON.stringify 转换为 JSON 字符串
// 然后使用 localStorage 保存在 session 名称里
localStorage.setItem('session', JSON.stringify(session));

// 然后是如何转换通过 JSON.stringify 生成的字符串,该字符串以 JSON 格式保存在 localStorage 里
var restoredSession = JSON.parse(localStorage.getItem('session'));

// 现在 restoredSession 包含了保存在 localStorage 里的对象
console.log(restoredSession);
</pre>
<h2 id=".E8.A7.84.E8.8C.83">规范</h2>
<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范名称及链接</th>
   <th scope="col">规范状态</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.12.3', 'JSON.stringify')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-json.stringify', 'JSON.stringify')}}</td>
   <td>{{Spec2('ES6')}}</td>
  </tr>
 </tbody>
</table>
<h2 id=".E6.B5.8F.E8.A7.88.E5.99.A8.E5.85.BC.E5.AE.B9.E6.80.A7">浏览器兼容性</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Chrome</th>
    <th>Firefox (Gecko)</th>
    <th>Internet Explorer</th>
    <th>Opera</th>
    <th>Safari</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{ CompatVersionUnknown() }}</td>
    <td>{{ CompatGeckoDesktop("1.9.1") }}</td>
    <td>8.0</td>
    <td>10.5</td>
    <td>4.0</td>
   </tr>
  </tbody>
 </table>
</div>
<div id="compat-mobile">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</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>Basic support</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=".E7.9B.B8.E5.85.B3.E9.93.BE.E6.8E.A5">相关链接</h2>
<ul>
 <li><a href="/zh-CN/docs/Web/JavaScript/Guide/Using_native_JSON">使用原生的 JSON 对象</a></li>
</ul>
Revert to this revision