值得注意:JSON是一种数据格式,不是一种语言,虽然与JS中定义对象字面量的形式相似,但JSON不从属于JavaScript,因为其它语言(如:PHP,JSP)中也有针对JSON的解析和序列化的方法操作。
语法
JSON可以表示以下三种值:
- 简单值:如字符串、数值、布尔值和null,但不支持undefined
- 对象:对象作为一种复杂的数据类型,表示是一组无序的键值对儿,值可以是简单值也可以复杂的数据
- 数组:数组作为一种复杂的数据类型,表示是一组有序的列表儿,可以通过索引来获取引用的值,值可以是简单值,也可以复杂数据对象
一个简单的JSON示例:
{
"name":"李三",
"age": 12,
grade:[
{
"course":"math"
"grade":99
},
{
"course":"math"
"grade":87
}
]
}
非常重要:JSON对象的属性(如上例中的“name”)必须加双引号。
在实际使用中,经常会因为上面使用单引号或不使用引号造成序死化错误,从而无法生成JSON对象。
序列化
JSON被大家所认可,除了语法是JavaScript语法子集,更主要是可以直接eval序列化(但有一定风险,可能会执行一些恶意代码,如读cookie等)成可用的JS对象直接使用。ECMAScript 5对解析JSON进行规范,定义了全局对象JSON,支持的浏览器有:IE8+,Firefox 3.5+,Safari4+,Chrome和Opera 10.5+;
JSON对象提供两个方法:stringify()和parse(),stringify()是将JSON对象转成字符串,而parse()则是将符合规范的字符串转成可用JSON对象。
stringify()
JSON.stringify(value [, replacer] [, space])
value:JSON对象。
replacer:过滤器(可选的),可以是方法或数组,用于过滤操作,如果是数组,则序列化字符串只包含数组中指定的值的JSON属性及属性值,如果是方法,方法传递key,value,可以对JSON对象每一个属性值及值进行处理后返回。
space:是否保留缩进,默认不保留,并且删除所有换行。
1.如果省略的话,那么显示出来的值 就没有分隔符。直接输出来2.如果是一个数字的话,那么它就定义缩进几个字符,当然 如果大于10 ,则最大值为10.
3.如果是一些转义字符,比如“\t”,表示回车,那么它每行一个回车。
4.如果仅仅是字符串,OK,就在每行输出值的时候把这些字符串附加上去就OK。当然,最大长度也是10个字符
实例:
var student = new Object(); student.name = "Lanny"; student.age = "25"; student.location = "China"; var json = JSON.stringify(student); alert(json); //{"name":"Lanny","age":"25","location":"China"}
使用数组过滤,只保留:name及locaiton
var json = JSON.stringify(student,["name","location"]); alert(json);//{"name":"Lanny","location":"China"}
使用函数过滤,对于name属性值单独处理,在之前输出:”my name is :”
使用缩进,缩进4个空白:var json = JSON.stringify(student, function (key, value) { switch (key){ case "name": return "my name is " + value; default : return value; } }); alert(json);//{"name":"my name is Lanny","age":"25","location":"China"}
var json = JSON.stringify(student,null,4);alert(json);//返回结果如下:{"name": "Lanny","age": "25","location": "China"}
parse()
JSON.parse(text [, reviver])
参数
text :必需。 一个有效的 JSON 字符串。
reviver :可选。 一个转换结果的函数。 将为对象的每个成员调用此函数。 如果成员包含嵌套对象,则先于父对象转换嵌套对象。 对于每个成员,会发生以下情况:
-
如果 reviver 返回一个有效值,则成员值将替换为转换后的值。
如果 reviver 返回它接收的相同值,则不修改成员值。
-
如果 reviver 返回 null 或 undefined,则删除成员。
返回值:一个对象或数组
示例:
var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}'; var contact = JSON.parse(jsontext);
以下示例演示了如何使用 JSON.stringify 将数组转换成 JSON 字符串,然后使用 JSON.parse 将该字符串还原成数组。
// Output: var arr = ["a", "b", "c"]; var str = JSON.stringify(arr); document.write(str); document.write ("<br/>"); var newArr = JSON.parse(str); while (newArr.length > 0) { document.write(newArr.pop() + "<br/>"); } // Output: ["a","b","c"] c b a
使用eval解析json字符串
var data ='{"firstname":"Jesper","surname":"Aaberg"}';
var dataObj=eval("("+data+")");//转换为json对象
为什么要 eval这里要添加 “("("+data+")");//”呢?
原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。
加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语 句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始 和结束标记,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]
对于这种写法,在JS中,可以到处看到。
如: (function()) {}(); 做闭包操作时等。
相关文章: