guoshuai93 / blog

19 stars 2 forks source link

大话 JSON #7

Open guoshuai93 opened 7 years ago

guoshuai93 commented 7 years ago

大话 JSON

何为 JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

JSON 都有以下形式:

JSON 对象拥有的方法

JSON.parse() is for "parsing" something that was received as JSON.
JSON.stringify() is to create a JSON string out of an object/array.

两个方法的作用是恰好相反的。

1. JSON.parse( text [, reviver] )

JSON.parse() 方法解析一个JSON字符串,构造由字符串描述的JavaScript值或对象。可以提供可选的reviver函数以在返回之前对所得到的对象执行变换。

JSON.parse() 不允许用逗号结尾

示例:

// 基本例子
JSON.parse('{}');              // {}
JSON.parse('true');            // true
JSON.parse('"foo"');           // "foo"
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
JSON.parse('null');            // null

// 使用 reviver 函数(还原函数)
JSON.parse('{"1": 1, "2": 2,"3": {"4": 4, "5": {"6": 6}}}', function (k, v) {
    console.log(k); // 输出当前的属性名,从而得知遍历顺序是从内向外的,
                    // 最后一个属性名会是个空字符串。
    return v;       // 返回原始属性值,相当于没有传递 reviver 参数。
});

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

参数

注意:

示例:

// 基本例子
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: undefined, y: Object, z: Symbol("")}); 
// '{}'

JSON.stringify([undefined, Object, Symbol("")]);          
// '[null,null,null]' 

replacer 参数

// 参数为 函数
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); //  {"week":45,"month":7}

// 参数为 Array
JSON.stringify(foo, ['week', 'month']);  
// '{"week":45,"month":7}', 只保留“week”和“month”属性值。

space 参数

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

大话JSON

3. toJSON

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

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

Date.prototype.toJSON()
原生 Date对象有一个 toJSON() 方法,将 Date() 对象转换成 ISO 8601 日期字符串。见;

var jsonDate = (new Date()).toJSON();// "2017-07-27T09:57:03.706Z"

JSON 和 JavaScript

JSON 基于 JavaScript 而来,但又不完全一样,所以严格来说 JSON 并不是 JavaScript 的子集

JavaScript JSON
对象和数组 属性名称必须是双引号字符串;后缀逗号被禁止。最后一个属性后面不能有逗号。
数值 前导0是禁止的(在JSON.stringify 0将被忽略,但在JSON.parse它将抛出SyntaxError);小数点后必须至少有一位数字。
字符串 只有有限的一些字符可能会被转义;禁止某些控制字符; Unicode 行分隔符 (U+2028) 和段分隔符 (U+2029)被允许 ; 字符串必须是双引号。请参见以下示例,其中 JSON.parse() 能够正常解析,但把它当作JavaScript解析时会抛出 SyntaxError 错误:

字符串解析错误:

    let code = '"\u2028\u2029"';
    JSON.parse(code);  // 工作正常
    eval(code);  // 失败

参考来源

Introducing JSON
JSON--MDN
JSON: The JavaScript subset that isn't( JSON 不是 JavaScript 的子集 )