JSON

下述内容主要讲述了《JavaScript高级程序设计(第3版)》第20章关于“JSON”。

JSON(JavaScript Object Notation, JS对象标记)是一种数据格式,不是一种编程语言。JSON和JavaScript对象区别,就像“斑马线”和“斑马”,“斑马线”基于“斑马”身上的条纹来呈现和命名,但是“斑马”和“斑马线”是两种东西。不要混淆!

对比内容

JSON

JS对象

键名

必须加双引号

可以允许不加、加单引号、加双引号

属性值

只能是数值(10进制)、字符串(双引号)、布尔值、null、对象

随意(函数、NaN、Infinity、undefined)

逗号问题

最后一个属性后面不能有逗号

可以

传输

可以跨平台数据传输,速度快

不可以

一、语法

JSON的语法可以表示三种类型的值: (1)简单值:可以在JSON中表示字符串(必须使用双引号)、数值、布尔值和null;但不支持JavaScript中的特殊值undefined。 (2)对象:对象的属性必须加双引号。

{
    "name": "liang",
    "age": 26,
    "married": false,
    "address": null
}

(3)数组:["ligang", 25, false, null]

二、解析和序列化

早期JSON解析器基本上就是使用JavaScript的eval()函数;其存在一定的风险,可能执行一些恶意代码。 对于不能原生支持JSON解析的浏览器,github上提供了比较优秀的shim方法:JSON-js

JSON.stringfy(“JavaScript对象”, “过滤器”, “是否缩进”):把一个JavaScript对象序列化为一个JSON字符串;值为undefined的属性会被跳过。

示例:undefined会被忽略

var person = {
    name: "liang",
    age: 26,
    address: undefined
}
JSON.stringify(person);     // "{"name":"liang","age":26}"

示例:过滤结果

var ary = [
    {name: "ligang", age: 26, sex: "male"},
    {name: "camile", age: 26, sex: "female"}
];

(1)第二个参数是一个数组,返回只包含name和age

JSON.stringify(ary, ["name", "age"]);   
// 结果:"[{"name":"ligang","age":26},{"name":"camile","age":26}]"

(2)第二个参数是一个函数

JSON.stringify(ary, function(key, value) {
    switch(key) {
        case "name":
            return value;
        case "age":
            return undefined;
        case "sex":
            return value === "male" ? "男" : "女";
        default:
            return value;
    }
});
// 结果:"[{"name":"ligang","sex":"男"},{"name":"camile","sex":"女"}]"

注意:如果函数返回了undefined,那么相应的属性会被忽略

(3)第三个参数控制结果中的缩进和空白符。 如果是一个数值,那他表示的是每个级别缩进的空格数;最大缩进空格数为10,大于10的自动转化为10。 如果是非数值,则这个字符将在JSON字符串中被用作缩进符(不再使用空格)。

var person = {
    name: "ligang",
    address: {
        province: "shandong",
        city: "yantai"
    }
};
JSON.stringify(person, null, 4);
// 结果:
{
    "name": "ligang",
    "address": {
        "province": "shandong",
        "city": "yantai"
    }
}"

JSON.stringify(person, null, "--");
// 结果:
"{
--"name": "ligang",
--"address": {
----"province": "shandong",
----"city": "yantai"
--}
}"

(4)toJSON()方法,自定义序列化需求

var person = {
    name: "ligang",
    age: 26,
    toJSON: function() {
        return this.name + "|" + this.age;
    }
};
JSON.stringify(person);
// 结果:""ligang|26""

把一个对象传入JSON.stringify(),序列化该对象的顺序如下:

  1. 如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
  2. 如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
  3. 对第(2)步返回的每个值进行相应的序列化。
  4. 如果提供了第三个参数,执行相应的格式化。
var person = {
    firstName: "li",
    lastName: "gang",
    age: 26,
    toJSON: function() {
        return {name: this.firstName + this.lastName, age: this.age};
    }
};
JSON.stringify(person, function(key, value){
    switch(key){
        case "age":
            return undefined;
        default:
            return value;
    }
}, "--");
// 结果:
"{
--"name": "ligang"
}"

(5)序列化数值,精度丢失

JSON.stringify({id:14812712740571735}); // "{"id":14812712740571736}"

根据国际标准IEEE 754,64位浮点数格式的64个二进制位中,第0位到第51位储存有效数字部分,第52到第62位储存指数部分,第63位是符号位,0表示正数,1表示负数。因此,JavaScript提供的有效数字的精度为53个二进制位(IEEE 754规定有效数字第一位默认为1,再加上后面的52位),也就是说,绝对值小于2的53次方的整数,即-(Math.pow(2, 53)-1)Math.pow(2, 53)-1,都可以精确表示。即16位数!

转成字符串可以解决这个问题!!!

JSON.stringify({id:"14812712740571735"});   // "{"id":"14812712740571735"}"

三、解析选项

JSON.parse(jsonText, fn),将JSON字符串解析为JavaScript值。fn将在每个键值对上调用。如果函数返回undefined,则要从结果中删除相应的键。

var person = {
    name: "ligang",
    age: 26,
    birthday: new Date(1990, 02, 28)
};
var jsonText = JSON.stringify(person);  // "{"name":"ligang","age":26,"birthday":"1990-03-27T16:00:00.000Z"}"
var jsonObj = JSON.parse(jsonText, function(key, value) {
    if(key === "birthday") {
        return new Date(value);
    }else {
        return value;
    }
});
console.log(jsonObj.birthday.getFullYear());    // 1990

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【译】JavaScript中的Callbacks

    你是否遇到过"callbacks"一词,但是不知道这意味着什么?别着急。你不是一个人。许多JavaScript的新手发现回调也很难理解。

    嘉明
  • FME中,如何更优雅的使用正则表达式?

    正则表达式是文本字符串处理的瑞士军刀。在FME中,常用来处理文本字符串的转换器主要为:StringSearcher 、StringReplacer。如图(1)所...

    数据处理与分析
  • 【译】发布你自己的npm包

    如今,NPM已经成为javascript库的事实上的注册表。特别是React,Angular和其他前端库主导的网络和node.js接管的服务器端,NPM软件包比...

    嘉明
  • react实战:umi问卷发布系统

    技术团队中,保持技术分享和持续的学习是完全必要的。企业主会说:"公司不是培训机构。"这固然正确。但一个公司,总会遇到这种或那种需要攻关的难题。当你不愿意分享解决...

    一粒小麦
  • 正则在FME中的应用

    能看到此文,我就粗暴的认为你已经对FME有了一定的了解。不了解没关系可以去FME博客进行学习,也可以去看FME十分钟进行相关的了解。下面我将结合...

    数据处理与分析
  • 【译】怎么写一个JavaScript Promise

    JavaScript promise是一个对象,表示异步任务完成或者失败及其结果值。

    嘉明
  • Webpack 5有哪些值得期待▶️

    早在今年(2019年)的2月份,Webpack核心团队的Sean Larkin就做过一次关于webpack 5新特性的演讲,为大家讲述了webpack 5目前的...

    用户1687375
  • Android使用WebView开发常见的坑

    现在的App基本上都会使用Native+H5的方式来开发的,例如网易新闻详情页面,微信公号详情页面都会使用WebView开发。这样可以很容易实现图文排版的需求,...

    阳仔
  • 【译】JavaScript中的Promises

    你有没有在JavaScript中遇到过promises并想知道它们是什么?它们为什么会被称为promises呢?它们是否和你以任何方式对另一个人做出的承诺有关呢...

    嘉明
  • 【译】JavaScript中的async/await

    异步的JavaScript从未如何简单!过去段时间,我们使用回调。然后,我们使用promises。现在,我们有了异步功能函数。

    嘉明

扫码关注云+社区

领取腾讯云代金券