仰望星空的天台

0%

JSON学习笔记

绪论

谈到JSON,就不的不谈起,交互这个关键词 准确一些,前后端数据交换问题

用户在前端页面提交数据,要以一个通用的格式传递给后端数据库 后端数据库得到前端页面请求数据,要以一个通用的格式把数据包传递给后端

看起来好像很抽象, 但实际上数据交换本身不是那么的严格 你可以直接丢一大堆HTML代码,甚至一大堆字符串, 但是,计算机不是人,他需要有一种固定,冗余度小的格式来支撑数据内容 (其实就算是人,面对那么多数据一大堆字符串也会傻眼)

PS.我们可以类比一下英语的语法和单词 把数据类比成一个个单词 语法类比成数据传输格式

把服务器和用户交互 或者 服务器和服务器之间的交互 类比成人与人之间说话

试想一下如果一个人和你说话 只说一堆单词,没有其他的语法 你能不能和他沟通?

所以,我们需要一种通用的格式来规范数据, 这个通用的形式 业界名曰:”互联网传输结构化数据”

但是,计算机没有人类通常意义上的语法 一般是用语言来规范语言

XML 扩展标记语言(EXtensible Markup Language)

在01年以前JSON还没出现的时候,XML一直是网上通用的互联网传输结构化数据的事实标准 使用DTD(document type definition)文档类型定义来组织数据,一度成为业界公认的标准 突出特点就是

1.格式统一
2.跨平台和语言
3.结构冗余繁琐
4.描述复杂结构能力较强

xml是使用标签对来描述数据内容的

JSON(JavaScript Object Notation)

JSON也是一种轻量级的数据交换格式,特点是

1.简单易读
2.轻量级
3.传输速度比XML快
4.描述复杂结构能力较弱
5.支持多种语言
6.能够使用内建的 JavaScript eval() 方法进行解析

JSON是使用键值对的形式来描述数据

关于JSON和XML之间相互转化

关于两种语法的相互转化 你可以类比成两种语言互相翻译

常规转化


XML
<Book>半生缘</Book>

JSON
{"Book":"半生缘"}

两者可以互译

没有属性标签结点的转换


XML
<line>
	<item>半生缘</item>
	<item>十八春</item>
</line>

JSON

{
  "line": {
    "item": [
      "半生缘",
      "十八春"
    ]
  }
}

两者可以互译

含有属性标签结点的转换


XML

<book class="101">半生缘</book>

JSON

{
	"book":
	{
		"@CLASS":"101",
		"#text":"半生缘"
	}
}

两者还是可以互译

有顺序性结点的转化

XML
<template> 
  <block>天空</block>  
  <line>地平线</line>  
  <block>地下</block> 
</template>

JSON

{
  "template": {
    "block": [
      "天空",
      "地下"
    ],
    "line": "地平线"
  }
}

这样两者就不能互译了(因为从xml转换到JSON 数据顺序改变了)

所以总的来说,XML结构上比JSON更加清晰 当然结构上的清晰导致,也导致代码较JSON更加冗余 所以我们一般使用结构性好的XML来做配置文件(复杂数据结构) 用冗余度较低,传输快的JSON来做数据格式传递(简单数据结构)

JSON语法

前面说了那么多,终于到了本文主要研究的重点了 JSON支持Javascript中除undefined之外的所有数据类型 JSON 根据数据的不同可以有三种表现形式(语法)

JSON解释简单值的形式


数值
NaN
JSON
NaN

字符串
I love you
JSON
"I love you"

很简单,但是实际应用中,简单值只是基础,JSON需要解释更多更复杂的数据类型

JSON解释对象


使用javascript 字面量解释对象
	var book = 
	{
		name : "半生缘",
		author : "张爱玲"
	}

JSON解释 对象
	{
		"name" : "半生缘",
		"authot" : "张爱玲"
	}

不同点有两个
1)js 需要声明一个变量引用  var book,JSON不硬性需要
2)JSON的属性名加 " " ( 重点强调 一定是" "  ' '都不行 不然会出错 )

JSON的遍历

如果我们需要遍历一个对象
比如
var person =
	{
		"name" : "owen",
		"age" : 19,
		"work" : "FrontEnd" 
	}


for(i in data)

索引i 就是对象的属性名
data[i] 就是对象对应属性的值

stringify方法

用于将JSON转换成字符串


var person = 
{
	"name" : "owen",
	"age" : 19,
	"work" : "FrontEnd",
	"school" : ["Meishan middle school" , "SSFL"]
}

这里我有一个JSON对象,并且我用person 来装它

然后我用stringify把变成字符串,并且用一个jsontext来装字符串

var jsontext = JSON.stringify( person );

得到的是一个字符串

" Javascript练习.js:2764 {"name":"owen","age":19,"work":"FrontEnd","school":["Meishan middle school","SSFL"]}  "


我们还可以给stringify方法 添加筛选条件参数

这个条件嘛 可以是两种

一种是数组形式
另外一种是函数形式




数组形式 :

var jsontext = JSON.stringify( person , ["name" , "age"] );

如果这么写,那么返回的字符串就是

" {"name":"owen","age":19}  "

因为work属性不在选定的条件范围,所以它被过滤了


函数形式 :

var jsontext = JSON.stringify( person , function( index , attribute ){
	switch( index )
	{
		case "school" : return attribute.join(",");
		//把数组数据的逗号去掉

		case "age" : return 18;
		//可以设置缺省值,无论实际年龄多少岁,都是永远的十八岁 哈哈

		case "work" : return undefined;
		//再次强调一遍 JSON 在JS所有数据类型中 只有undefined不能解释 所以work属性不能输出

		default : return attribute;
		//其他的属性正常输出
	}

	//当然这里的switch也可以改写成if...else
	if( index == "school" )
	{
		return attribute.join(",");
	}
	else if( index == "age" )
	{
		return 18;
	}else if( index == "work")
	{
		return undefined;
	}else
	{
		return attribute
	}
});

那么得到的结果是
" {"name":"owen","age":18,"work":"FrontEnd","school":"Meishan middle school,SSFL"} "

parse方法

可以将有效的JSON格式的字符串 转换成JSON对象


var datatext = '{	"name" : "owen","school" : ["MeiShan Middle school" , "SSFL" ] }';
var data = JSON.parse( datatext );
console.log(data);

打印出
 Object { name="owen",  school=[2]}

其中school数组数据 在火狐展开

name
	"owen"
school
	["MeiShan Middle school", "SSFL"]

	0	"MeiShan Middle school"	
	1	"SSFL"

toJSON方法

toJSON方法是从对象内部筛选属性的方法


var book = 
	{
		"title" : ["JavaScript","HTML5"],
		"authors" : "Owen",
		"year" : "2015",
		toJSON : function(){
		//切记这里不能少了this
			return this.authors;
		}
	};

	var jsontext = JSON.stringify( book );

console.log(jsontext);//只输出 "Owen"


var book = 
	{
		"title" : ["JavaScript","HTML5"],
		"authors" : "Owen",
		"year" : "2015",
		toJSON : function(){
			return this.title[1];
		}
	};

	var jsontext = JSON.stringify( book );

console.log(jsontext);//只输出 "HTML5"

关于对象引用会出现的一些问题


直接上代码:
var a = {
	"name" : "Owen",
	"age" : 19
	};

var b = a;
b.name = "Zyz";

console.log( a.name );//Zyz

之所以出现这样的问题,是因为
我把a赋值给b的只是一个对象的引用而已
也就是说 这个JSON对象并没有被复制
被复制的只是这个指向这个对象的指针而已

那应该怎么解决呢?
var b = {};
for(i in a)
{
	b[i] = a[i];
}
console.log( a["name"] );

但是 我们分析一下由此产生的另外一个问题
试想,如果a对象里面还有一个对象
那么我们这样单纯的遍历赋值 也会产生上文提到的引用问题
所以,我们需要进行如下改进

var b = JSON.parse(JSON.stringify(a));
console.log( a.name );
先将a解析成字符串 然后再将这个字符串 解析回对象 赋值给b
这样就能解决对象引用的问题

感谢

本博文,有相当一部分内容COPY 和 引用了他人的知识,特此陈列,以表感谢

妙味课堂 关于JS中的JSON对象

引用出自

《javascript高级程序设计》

Table of Contents