• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • JSON

    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)被允许; 字符串必须用双引号括起来。请参考下面的示例,可以看到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+000A)以及空格(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。

    下篇:JSON.parse()