`JSON`对象包含两个方法: 用于解析 JavaScript Object Notation (JSON) 的 `parse()` 方法，以及将对象/值转换为 JSON字符串的 `stringify()` 方法。除了这两个方法, JSON这个对象本身并没有其他作用，也不能被调用或者作为构造函数调用。

## 描述

### JavaScript Object Notation

JSON 是一种语法，用来序列化对象、数组、数值、字符串、布尔值和 `null` 。它基于 JavaScript 语法，但与之不同：JavaScript不是JSON，JSON也不是JavaScript。参考 JSON：并不是JavaScript 的子集。

JavaScript 与 JSON 的区别
JavaScript类型 | JSON 的不同点
--- | ---
对象和数组 | 属性名称必须是双引号括起来的字符串；最后一个属性后不能有逗号。
数值 | 禁止出现前导零（ JSON.stringify 方法自动忽略前导零，而在 JSON.parse 方法中将会抛出 SyntaxError）；如果有小数点, 则后面至少跟着一位数字。
字符串 | 只有有限的一些字符可能会被转义；禁止某些控制字符； Unicode 行分隔符 （U+2028）和段分隔符 （U+2029）被允许 ; 字符串必须用双引号括起来。请参考下面的示例，可以看到 `JSON.parse()` 能够正常解析，但将其当作JavaScript解析时会抛出 `SyntaxError` 错误：
    let code = '"\u2028\u2029"';
    JSON.parse(code);  // 正常
    eval(code);  // 错误

完整的JSON语法定义如下：

    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

可以有多余的空白字符出现在`JSONNumber`（数字内部不允许包含空格）或`JSONString`（字符串内部的空格被解释为相应的字符，否则就有问题了）之外的任何位置。JSON只支持这些空白字符： 制表符（U+0009），回车（U+000D），换行（U+0020）以及空格（U+0020）。

## 方法

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

## Polyfill

`JSON`对象可能不被老版本的浏览器支持。可以将下面的代码放到JS脚本最开始的位置，这样就可以在没有原生支持 JSON 对象的浏览器（如IE6）中使用 `JSON`对象。

以下算法是对原生`JSON`对象的模仿：

    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 < 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) + '"';
          };
        })()
      };
    }

业界更专业, 更强大的`JSON`对象 polyfills 是 JSON2 和 JSON3。

## 规范

规范 | 状态 | 说明
--- | --- | ---
ECMAScript 5.1 (ECMA-262) JSON | Standard | Initial definition.
ECMAScript 2015 (6th Edition, ECMA-262) JSON | Standard |
ECMAScript Latest Draft (ECMA-262) JSON | Draft |

## 浏览器兼容性

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
`JSON` | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 3.5 | IE Full support 8 | Opera Full support 10.5 | Safari Full support 4 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes
`parse` | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 3.5 | IE Full support 8 | Opera Full support 10.5 | Safari Full support 4 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes
`stringify` | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 3.5 | IE Full support 8 | Opera Full support 10.5 | Safari Full support 4 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes
JavaScript is a superset of JSON | Chrome Full support 66 | Edge No support No | Firefox Full support 62 | IE No support No | Opera Full support 53 | Safari Full support Yes | WebView Android Full support 66 | Chrome Android Full support 66 | Edge Mobile No support No | Firefox Android Full support 62 | Opera Android Full support 53 | Safari iOS Full support Yes | Samsung Internet Android No support No | nodejs Full support 10.0.0

### Legend

Full support
  Full support
No support
  No support

## 相关链接

- `Date.prototype.toJSON()`