2019-04-21 11:50:48 +08:00

253 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<article id="wikiArticle">
<div></div>
<p><code><strong>JSON.stringify()</strong></code> 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串如果指定了replacer是一个函数则可以替换值或者如果指定了replacer是一个数组可选的仅包括指定的属性。</p>
<h2 id="Syntax" name="Syntax">语法</h2>
<pre><code class="language-javascript"><code>JSON.stringify(<em>value</em>[, <em>replacer</em> [, <em>space</em>]])</code>
</code></pre>
<h3 id="Parameters" name="Parameters">参数</h3>
<dl>
<dt><code>value</code></dt>
<dd>将要序列化成 一个JSON 字符串的值。</dd>
<dt><code>replacer</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd>如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中如果该参数为null或者未提供则对象所有的属性都会被序列化关于该参数更详细的解释和示例请参考<a class="new" href="Guide/Using_native_JSON#The_replacer_parameter" rel="nofollow">使用原生的 JSON 对象</a>一文。</dd>
<dt><code>space</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd>指定缩进用的空白字符串用于美化输出pretty-print如果参数是个数字它代表有多少的空格上限为10。该值若小于1则意味着没有空格如果该参数为字符串(字符串的前十个字母)该字符串将被作为空格如果该参数没有提供或者为null将没有空格。</dd>
<dt>
<h3 id="返回值">返回值 </h3>
<p>一个表示给定值的JSON字符串。</p>
<p> </p>
</dt>
</dl>
<h2 id="描述">描述</h2>
<p>关于序列化,有下面五点注意事项:</p>
<ul>
<li>非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。</li>
<li>布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。</li>
<li><code>undefined、</code>任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 <code>null</code>(出现在数组中时)。</li>
<li>对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。</li>
<li>所有以 symbol 为属性键的属性都会被完全忽略掉,即便 <code>replacer</code> 参数中强制指定包含了它们。</li>
<li>不可枚举的属性会被忽略</li>
</ul>
<pre><code class="language-javascript">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}"
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";
        }
    }
);
// undefined
// 不可枚举的属性默认会被忽略:
JSON.stringify( 
    Object.create(
        null, 
        { 
            x: { value: 'x', enumerable: false }, 
            y: { value: 'y', enumerable: true } 
        }
    )
);
// "{"y":"y"}"
</code></pre>
<h3 id="replacer参数"><code>replacer参数</code></h3>
<p>replacer参数可以是一个函数或者一个数组。作为函数它有两个参数键(key)值(value)都会被序列化。</p>
<ul>
<li>如果返回一个 <a href="Reference/Global_Objects/Number" title="JavaScript 的 Number 对象是经过封装的能让你处理数字值的对象。Number 对象由 Number() 构造器创建。"><code>Number</code></a>, 转换成相应的字符串被添加入JSON字符串。</li>
<li>如果返回一个 <a href="Reference/String" title="此页面仍未被本地化, 期待您的翻译!"><code>String</code></a>, 该字符串作为属性值被添加入JSON。</li>
<li>如果返回一个 <a href="Reference/Boolean" title="此页面仍未被本地化, 期待您的翻译!"><code>Boolean</code></a>, "true" 或者 "false"被作为属性值被添加入JSON字符串。</li>
<li>如果返回任何其他对象该对象递归地序列化成JSON字符串对每个属性调用replacer方法。除非该对象是一个函数这种情况将不会被序列化成JSON字符串。</li>
<li>如果返回undefined该属性值不会在JSON字符串中输出。</li>
</ul>
<p><strong>注意:</strong> 不能用replacer方法从数组中移除值(values)如若返回undefined或者一个函数将会被null取代。</p>
<h4 id="例子(function)">例子(function)</h4>
<pre><code>function replacer(key, value) {
if (typeof value === "string") {
return undefined;
}
return value;
}
var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};
var jsonString = JSON.stringify(foo, replacer);</code></code></pre>
<p>JSON序列化结果为 <code>{"week":45,"month":7}</code>.</p>
<h4 id="例子(array)">例子(array)</h4>
<p><code>如果replacer是一个数组数组的值代表将被序列化成JSON字符串的属性名。</code></p>
<pre><code>JSON.stringify(foo, ['week', 'month']);
// '{"week":45,"month":7}', 只保留“week”和“month”属性值。</code></code></pre>
<h3 id="space_参数"><code>space</code> 参数</h3>
<p>space 参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格最多10个空格如果是一个字符串则每一级别会比上一级别多缩进用该字符串或该字符串的前十个字符</p>
<pre><code class="language-javascript">JSON.stringify({ a: 2 }, null, " "); // '{\n "a": 2\n}'</code></pre>
<p>使用制表符(\t来缩进</p>
<pre><code class="language-javascript">JSON.stringify({ uno: 1, dos : 2 }, null, '\t')
// '{ \
// "uno": 1, \
// "dos": 2 \
// }'
</code></pre>
<h3 id="toJSON_方法">toJSON 方法</h3>
<p>如果一个被序列化的对象拥有 <code>toJSON</code> 方法,那么该 <code>toJSON</code> 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 <code>toJSON</code> 方法后的返回值会被序列化,例如:</p>
<pre><code class="language-javascript">var obj = {
foo: 'foo',
toJSON: function () {
return 'bar';
}
};
JSON.stringify(obj); // <code>'"bar"'</code>
JSON.stringify({x: obj}); // <code>'{"x":"bar"}'</code>
</code></pre>
<h3 id="JSON.stringify用作_JavaScript"><code>JSON.stringify</code>用作 JavaScript</h3>
<p>注意JSON不是javascript严格意义上的子集在JSON中不需要省略两条终线(Line separator和Paragraph separator)但在JavaScript中需要被省略。因此如果JSON被用作JSONP时下面方法可以使用</p>
<pre><code>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"}</code></code></pre>
<h3 id="使用_JSON.stringify_结合_localStorage_的例子">使用 JSON.stringify 结合 localStorage 的例子</h3>
<p>一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象。下面的例子是 <code>JSON.stringify</code> 适用于这种情形的一个样板:</p>
<pre><code class="language-javascript">// 创建一个示例数据
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);
</code></pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">规范名称及链接</th>
<th scope="col">规范状态</th>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">JSON.stringify</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-json.stringify" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">JSON.stringify</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p></p><div class="blockIndicator warning"><strong><a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">We're converting our compatibility data into a machine-readable JSON format</a></strong>.
This compatibility table still uses the old format,
because we haven't yet converted the data it contains.
<strong><a class="new" href="/zh-CN/docs/MDN/Contribute/Structures/Compatibility_tables" rel="nofollow">Find out how you can help!</a></strong></div>
<div class="htab">
<a id="AutoCompatibilityTable" name="AutoCompatibilityTable"></a>
<ul>
<li class="selected"><a>Desktop</a></li>
<li><a>Mobile</a></li>
</ul>
</div><p></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><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
<td><a href="/en-US/Firefox/Releases/3.5" title="Released on 2009-06-30.">3.5</a> (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><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
<td><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
<td>1.0 (1.0)</td>
<td><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
<td><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
<td><span style="color: #888;" title="Please update this with the earliest version of support.">(Yes)</span></td>
</tr>
</tbody>
</table>
</div>
<h2 id="相关链接">相关链接</h2>
<ul>
<li><a class="new" href="Guide/Using_native_JSON" rel="nofollow">使用原生的 JSON 对象</a></li>
</ul>
</article>