aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/json/index.html
blob: 2afd07d2055c0bf7a02fc65f7d2d25917db916db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
---
title: JSON
slug: Web/JavaScript/Reference/Global_Objects/JSON
tags:
  - JSON
  - JavaScript
  - Object
  - Reference
  - 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")}}) 的 <code>parse()</code> 方法,以及将对象/值转换为 JSON字符串的 <code>stringify()</code> 方法。除了这两个方法, JSON这个对象本身并没有其他作用,也不能被调用或者作为构造函数调用。</p>

<h2 id="Description">描述</h2>

<h3 id="JavaScript_Object_Notation">JavaScript Object Notation</h3>

<p><strong>JSON</strong> 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 {{jsxref("null")}} 。它基于 JavaScript 语法,但与之不同:<strong>JavaScript不是JSON,JSON也不是JavaScript</strong>。参考 <a href="http://timelessrepo.com/json-isnt-a-javascript-subset">JSON:并不是JavaScript 的子集</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>
    <p>属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号。</p>
   </td>
  </tr>
  <tr>
   <td>数值</td>
   <td>禁止出现前导零( JSON.stringify 方法自动忽略前导零,而在 JSON.parse 方法中将会抛出 SyntaxError);如果有小数点, 则后面至少跟着一位数字。</td>
  </tr>
  <tr>
   <td>字符串</td>
   <td>
    <p>只有有限的一些字符可能会被转义;禁止某些控制字符; Unicode 行分隔符 (<a href="http://unicode-table.com/cn/2028/">U+2028</a>)和段分隔符 (<a href="http://unicode-table.com/cn/2029/">U+2029</a>)被允许 ; 字符串必须用双引号括起来。请参考下面的示例,可以看到 {{jsxref("JSON.parse()")}} 能够正常解析,但将其当作JavaScript解析时会抛出 {{jsxref("SyntaxError")}} 错误:</p>

    <pre class="brush: js">
let code = '"\u2028\u2029"';
JSON.parse(code);  // 正常
eval(code);  // 错误
</pre>
   </td>
  </tr>
 </tbody>
</table>

<p>完整的JSON语法定义如下:</p>

<pre>JSON = null
    or true or false
    or JSONNumber
    or JSONString
    or JSONObject
    or JSONArray

JSONNumber = - PositiveNumber
          or PositiveNumber
PositiveNumber = DecimalNumber
              or DecimalNumber . Digits
              or DecimalNumber . Digits ExponentPart
              or DecimalNumber ExponentPart
DecimalNumber = 0
             or OneToNine Digits
ExponentPart = e Exponent
            or E Exponent
Exponent = Digits
        or + Digits
        or - Digits
Digits = Digit
      or Digits Digit
Digit = 0 through 9
OneToNine = 1 through 9

JSONString = ""
          or " StringCharacters "
StringCharacters = StringCharacter
                or StringCharacters StringCharacter
StringCharacter = any character
                  except " or \ or U+0000 through U+001F
               or EscapeSequence
EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t
              or \u HexDigit HexDigit HexDigit HexDigit
HexDigit = 0 through 9
        or A through F
        or a through f

JSONObject = { }
          or { Members }
Members = JSONString : JSON
       or Members , JSONString : JSON

JSONArray = [ ]
         or [ ArrayElements ]
ArrayElements = JSON
             or ArrayElements , JSON
</pre>

<p><code>JSONNumber</code>(数字内部不允许包含空格)或<code>JSONString</code>(字符串内部的空格被解释为相应的字符,否则就有问题了)之外的任何位置可以有多余的空白字符。JSON只支持这些空白字符: 制表符(<a href="http://unicode-table.com/en/0009/">U+0009</a>),回车(<a href="http://unicode-table.com/en/000D/">U+000D</a>),换行(<a href="http://unicode-table.com/en/0020/">U+00</a>0A)以及空格(<a href="http://unicode-table.com/en/0020/">U+0020</a>)。</p>

<h2 id="Methods">方法</h2>

<dl>
 <dt>{{jsxref("JSON.parse()")}}</dt>
 <dd>解析JSON字符串并返回对应的值,可以额外传入一个转换函数,用来将生成的值和其属性, 在返回之前进行某些修改。</dd>
 <dt>{{jsxref("JSON.stringify()")}}</dt>
 <dd>返回与指定值对应的JSON字符串,可以通过额外的参数, 控制仅包含某些属性, 或者以自定义方法来替换某些key对应的属性值。</dd>
</dl>

<h2 id="Polyfill">Polyfill</h2>

<p><code>JSON</code>对象可能不被老版本的浏览器支持。可以将下面的代码放到JS脚本最开始的位置,这样就可以在没有原生支持 JSON 对象的浏览器(如IE6)中使用 <code>JSON</code>对象。</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 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 &lt; value.length; i++)
              res += (i ? ', ' : '') + stringify(value[i]);
            return res + ']';
          } else if (toString.call(value) === '[object Object]') {
            var tmp = [];
            for (var k in value) {
              if (value.hasOwnProperty(k))
                tmp.push(stringify(k) + ': ' + stringify(value[k]));
            }
            return '{' + tmp.join(', ') + '}';
          }
        }
        return '"' + value.toString().replace(escRE, escFunc) + '"';
      };
    })()
  };
}
</pre>

<p>业界更专业, 更强大的<code>JSON</code>对象 <a class="external" href="http://remysharp.com/2010/10/08/what-is-a-polyfill/" title="http://remysharp.com/2010/10/08/what-is-a-polyfill/">polyfills</a> 是 <a class="link-https" href="https://github.com/douglascrockford/JSON-js" title="https://github.com/douglascrockford/JSON-js">JSON2</a> 和 <a class="external" href="http://bestiejs.github.com/json3" title="http://bestiejs.github.com/json3">JSON3</a></p>

<h2 id="Specifications">规范</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', '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="Browser_compatibility">浏览器兼容性</h2>

<p>{{Compat("javascript.builtins.JSON")}}</p>

<h2 id="See_also">相关链接</h2>

<ul>
 <li>{{jsxref("Date.prototype.toJSON()")}}</li>
</ul>