前端开发学习二——由JSON和Object Literal Notation引起的思考
这篇随笔是今天看公司原来的项目中引用JSON2.js,并调用stringify和parse两个方法在JavaSript Object Literal Notation和JSON之间转换引起的思考。
概念梳理:
JSON (JavaScript Object Notation, JavaScript对象表示法) 与Object Literal Notation(对象字面量表示法)
Object Literal Notation的中文翻译有很多,比如标题写的对象自变量表示法,又或者文字对象表示法等等,总觉得原来的英文术语翻译成中文就会经历一下“装箱”的过程,变得过于“专业”和“深奥”。好多时候这样的中文术语还不如英文原词来的轻松。
Object Literal Notation表示如下:
var person={
name: "tonny",
job: "Software Engineer"
}
JSON 是一种轻量级数据交换格式,采用完全独立于语言的文本格式
JavaScript Object Notation (JSON) is a lightweight, text-based, language- independent data interchange format. 参考来源:(http://www.ietf.org/rfc/rfc4627.txt)
data interchange format,language- independent,text-based 理清JSON的概念,关键在于这三点。
当两个应用程序、或者两台服务器、或者两种语言之间进行“交流”时,他们都趋向于采用字符串。原因显而易见,字符串是在所有语言中都可以解析的类型。复杂的数据结构在程序内部被描述成复杂的内存引用,而呈现的时候仅仅是加入了大括号、方括号、尖角括号或者空格等表示的字符串。当然,这个字符串是符合标准的语法要求的。JSON就是这些语法要求中的一种,可以将Object,Array,String,Number,Boolean和null描述成字符串,这样就可以在程序间进行传递了。当然在你需要的时候可以将这些字符串进行编码后传递。
是不是JSON?
{“name”: ”tonny”}
上面的表示是JSON么,它可以是对象常量(Object Literal)也可以是JSON字符串,关键是看他在上下文中是怎么运用的。例如:
var person='{ "name" : "tonny"}';
//this is a json string
var person={ "name" :"tonny" };
//this is an object literal
Object
Literal和JSON的区别:
JSON中:
Key值必须用双引号表示,单引号都不行。所有的字符串都必须加上双引号
Values可以是String、Number、Object、Array、true、false、null. No Function
从以上啰嗦的一段可以看到,我一直在强调字符串。所以JSON只是一种表示成字符串的数据交换格式。有种说法将对象字面量(JavaScript Object Literals)叫做“JSON Objects”,他们仅仅是看上去相似而已,然而这样的叫法是错误的。
然而,虽然对象字面量(JavaScript Object Literals)不可以叫做“JSON Objects“,单事实上存在JSON object,当然这和object literal完全是两码事了。
回到正题
好了,从这里开始回到我一开始的问题了。根据 ECMA-262(ECMAScript)第 5 版中描述,JSON 是一个包含了函数 parse 和 stringify 的简单对象。 parse 函数用来解析一个 JSON 文本(一个 JSON 格式的字符串)到一个 ECMAScript 值(例如 JSON 对象被解析为 ECMAScript 对象, JSON 数组被解析为 ECMAScript 数组,其它类型以此类推);stringify 则相反,它是将一个 ECMAScript 值解析为一个 JSON 格式的字符串, 比如将一个 ECMAScript 对象解析为一个 JSON 对象的字符串。JSON 对象是在 ECMAScript 第 5 版中实现的,此版于 2009 年 12 月发布;IE6 IE7 与 IE8(Q) (IE8的怪异模式相当于 IE 5.5) 发布时间比较早,没有在其 Javascript 引擎中实现该对象。在没有实现JSON对象的浏览器中,可以使用 window.eval() 或 new Function(){} 的方式解析 JSON 格式字符串。例如:
var jsonStr='{"key1":"value1","key2":"value2","key3":"value3"}';
var json1 = eval("(" + jsonStr + ")");
var json2 = (new Function("return" + jsonStr))();
var result1;
for(p in json1){
result1 += p + ":" + json1[p];
}
alert(result1);
for(p in json2){
result1 += p + ":" + json2[p];
}
alert(result2);
这种解析 JSON 格式字符串的简单实现存在安全问题,被插入的恶意 JSON 字符串(比如获取用户的 cookie 信息)可能被解析并执行。 可以使用一些经过验证的安全成熟的的解决方案,例如 json2.js 中的 JSON.parse() 或 jQuery.parseJSON()。
最后附上msdn中对JSON.stringify()和JSON.parse()方法调用的示例:
var contact = new Object();
contact.firstname = "Jesper";
contact.surname = "Aaberg";
contact.phone = ["555-0100", "555-0120"];
var memberfilter = new Array();
memberfilter[0] = "surname";
memberfilter[1] = "phone";
var jsonText = JSON.stringify(contact, memberfilter, "\t");
/* The value of jsonText is:
'{
"surname": "Aaberg",
"phone": [
"555-0100",
"555-0120"
]
}'
*/
var continents = new Array();
continents[0] = "Europe";
continents[1] = "Asia";
continents[2] = "Australia";
continents[3] = "Antarctica";
continents[4] = "North America";
continents[5] = "South America";
continents[6] = "Africa";
var jsonText = JSON.stringify(continents, replaceToUpper);
/* The value of jsonText is:
'"EUROPE,ASIA,AUSTRALIA,ANTARCTICA,NORTH AMERICA,SOUTH AMERICA,AFRICA"'
*/
function replaceToUpper(key, value) {
return value.toString().toUpperCase();
}
var contact = new Object();
contact.firstname = "Jesper";
contact.surname = "Aaberg";
contact.phone = ["555-0100", "555-0120"];
contact.toJSON = function(key)
{
var replacement = new Object();
for (var val in this)
{
if (typeof (this[val]) === 'string')
replacement[val] = this[val].toUpperCase();
else
replacement[val] = this[val]
}
return replacement;
};
var jsonText = JSON.stringify(contact);
/* The value of jsonText is:
'{"firstname":"JESPER","surname":"AABERG","phone":["555-0100","555-0120"]}'
*/
var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);
var fullname = contact.surname + ", " + contact.firstname;
// The value of fullname is "Aaberg, Jesper"
var jsontext = '{ "hiredate": "2008-01-01T12:00:00Z", "birthdate": "2008-12-25T12:00:00Z" }';
var dates = JSON.parse(jsontext, dateReviver);
var string = dates.birthdate.toUTCString();
// The value of string is "Thu, 25 Dec 2008 12:00:00 UTC"
function dateReviver(key, value) {
var a;
if (typeof value === 'string') {
a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
};
今天的探索就到这里了。我的问题理清了,花了好长的时间来写这篇文章,在理解后再整理写下来也不是一件容易的事,最直接的效果是可以更深的巩固自己的理解。OK。明天继续努力!