Javascript 中 JSON 的应用

写在前面: 略显�乏味,建议边阅读边查看RunJS 运行本文实例(取消勾选视图【HTML】【CSS】,更直观),更好的理解与吸收。

前言

JSON(JavaScript Object Notation) 是一种数据结构,JavaScript 原生格式,而非一种编程语言。

值类型

  • String, 双引号的反斜杠转义的 Unicode。
  • Number, 在 JavaScript 中的双精度浮点格式。
  • Boolean, true 或 false。
  • Array, 值的有序序列。
  • Object, 无序集合键值对。
  • Value, 它可以是一个字符串,一个数字,真的还是假(true/false),空 (null) 等。

结构

在 JSON 中,有两种结构:对象和数组。

  1. 对象以“{”(左括号)开始,“}”(右括号)结束。每个 key 后跟一个“:”(冒号);key 用双引号括起来;值之间用 “,”(逗号)分隔。value 如果是字符串则必须用双引号,数值型则不需要。例如:

     { "hello": "world", "age": 100 };
    
  2. 数组是值(value)的有序集合。数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间用 “,”(逗号)分隔。

应用

var books = [
      {
        "name": "javascript",
        "author": [
          "Michael",
          "Prince",
          "Banada"
        ],
        "price": 200,
        "date": new Date()
      }
    ],
    book = books[0];

双引号

key 必须使用双引号,如果 value 是字符串也必须使用双引号

可用JSONLint来验证自己写的 json 代码是否有错误。

当然也可以写个简单点验证函数:

function isJSON(string) {
    try {
        JSON.parse(string);
    }
    catch (e) {
        console.log('------json error---------');
        console.log(string);
        console.log(e);
        console.log('------json done----------');
        return false;
    }
    return true;
}

isJSON('{"hello": "world"}'); // true
isJSON("{'hello': 'world'}"); // �false

// output
------json error---------
{'hello': 'world'}
SyntaxError: Unexpected token ' in JSON at position 1
------json done----------

访问 key

两种方式访问,第一种调用属性,第二种哈希调用。

book.name;
book["name"];

判断是否含有某个键值:

book.hasOwnProperty("name");

所有key列表数组

Object.keys(book)

遍历及 顺序

仅遍历一级节点:

 var key, value;
 for(key in book) {
     console.log(key + ' - ' + JSON.stringify(book[key]));
 }

// output
name - "javascript"
author - ["Michael","Prince","Banada"]
price - 200
date - "2016-06-15T13:31:48.488Z"

顺序

  1. for-in 语句无法保证遍历顺序,应尽量避免编写依赖对象属性顺序的代码。如果想顺序遍历一组数据,请使用数组并使用 for 语句遍历。 如果想按照定义的次序遍历对象属性,请参考本文针对各浏览器编写特殊代码。

  2. Object.keys()也是被排过序的。

  3. 个人解决方案,把期望的顺序键值放入order_keys中:

    var response = {"商品编码":"12345","门店名单":"什么路店","SKU":"超市购物袋大号","order_keys":["SKU","商品编码","门店名单"]}, 
        order_keys = response.order_keys,
        key, value, i; 
        
    for(i = 0; i < order_keys.length; i ++) {
        key = order_keys[i];
        value = response[key];
    } 
    

stringify

JSON 对象转化为字符串。

JSON.stringify(books);

用法

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

参数

  • value

    必需, 通常为对象或数组。

  • replacer

    可选, 用于转换结果的函数或数组。

    • 数组,只列数组包含的属性。

      JSON.stringify(book, ["name", "price"]);
      
      // output
      // {"name":"javascript", "price":200}
      
    • 函数,两个参数: 属性的名与值。

      JSON.stringify(books, function(key, value){
              switch(key){
              case "author" :
                  return value.join("-");
              case "name" :
                  return value;
              case "price" :
                  return value * 50000;
              default:
                  return value;
          }
      });
      
      // output
      // [{"name":"javascript","author":"Michael-Prince-Banada","price":10000000,"date":"2016-06-15T12:45:54.181Z"}]
      
  • space

    可选, 向返回值 JSON 文本添加缩进、空格和换行符以使其更易于读取。

    • 如果省略 space,则将生成返回值文本,而没有任何额外空格。

    • 如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格。如果 space 大于 10,则文本缩进 10 个空格。

        JSON.stringify(book,null,4);
      
        // output
        {
            "name": "javascript",
            "author": [
                "Michael",
                "Prince",
                "Banada"
            ],
            "price": 200,
            "date": "2016-06-15T12:46:49.680Z"
        }
      
    • 如果 space 是一个非空字符串(例如 “\t”),则返回值文本在每个级别中缩进字符串中的字符。

        JSON.stringify(book,null,"-");
      
        // output
        {
        -"name": "javascript",
        -"author": [
        --"Michael",
        --"Prince",
        --"Banada"
        -],
        -"price": 200,
        -"date": "2016-06-15T12:47:27.553Z"
        }
      
    • 如果 space 是长度大于 10 个字符的字符串,则使用前 10 个字符。

返回值

JSON 数组格式字符串。

parse

字符串转化为 JSON 对象。

JSON.parse(JSON.stringify(books));

用法

JSON.parse(text [, reviver])

参数

  • text

    必需,有效的 JSON 字符串。

  • reviver

    可选, 转换结果的函数。 将为对象的每个成员调用此函数。 如果成员包含嵌套对象,则先于父对象转换嵌套对象。 对于每个成员,会发生以下情况:

    • 如果返回一个有效值,则成员值将替换为转换后的值。

        var new_book = JSON.parse(JSON.stringify(book), function(key,value){
            if(key === "date"){
                return new Date(value);
            }
            else {
                return value;
            }
        });
        new_book.date.getFullYear();
      
        // output: 2016
      
    • 如果返回它接收的相同值,则不修改成员值。

    • 如果返回 null 或 undefined,则删除了该成员。

返回值

对象或数组。

toJSON()

  • toJSON() 方法可以将 Date 对象转换为 JSON 字符串。

      var date = new Date()
          json = date.toJSON();
    
      console.log(date);
      console.log(json);
    
      // output
      // Wed Jun 15 2016 20:51:11 GMT+0800 (CST)
      // 2016-06-15T12:51:11.552Z
    
  • 如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 toJSON 方法后的返回值会被序列化,例如:

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

参考

更新日志

  • 16-06-16

    • 补充访问key方式、获取所有key列表, 及顺序遍历问题。
    • 补充判断是否存在key
    • 按期望顺序遍历,个人解决方案。

写在最后:有表达缺失、不到位或需要补充、修正的地方,欢迎反馈,提前感谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容