在本文中,我们将研究对象序列化的好处,当前浏览器的实现,并开发一些代码来帮助您基于Ajax的项目。
假设我们有一个使用文字符号定义的相当复杂的JavaScript对象:
var obj1 = {
b1: true,
s1: "text string",
n1: 12345,
n2: null,
n3: undefined,
a1: [ 1,1,2,3,5,8, [13, 21, 34] ],
o1: {
a: [3, 2, 1],
b: {
c: 42,
d: [ 3.14, 1.618 ]
}
}
};
我们可以通过多种方式访问任何对象属性:
obj1.s1; // returns "text string"
obj1["n1"]; // returns 12345
obj1.a1[6][1]; // returns 21
obj1["o1"]["b"]["c"]; // returns 42
该对象也可以传递给JavaScript函数和方法,而不必指定单个参数。 有用的东西。
但是,如果我们需要将该对象存储在cookie中怎么办? 如果我们需要通过Ajax请求将对象传递给Web服务怎么办? 如果该Web服务想要返回该对象的修改版本怎么办? 答案是序列化:
- 序列化是将任何对象转换为字符串的过程。
- 反序列化会将字符串转换回本地对象。
也许我们可以在JavaScript中使用的最好的字符串表示法是JSON-JavaScript Object Notation。 JSON是一种轻量级的数据交换格式,受JavaScript对象文字符号的启发,如上所示。 JSON受PHP和许多其他服务器端语言(请参阅json.org )支持。
JavaScript中有两种JSON方法:
- JSON.stringify( obj ) —将JavaScript对象转换为JSON字符串
- JSON.parse( str ) —将JSON字符串转换回JavaScript对象
不幸的是,很少有浏览器提供这些方法。 迄今为止,只有Firefox 3.5,Internet Explorer 8.0和Chrome 3 beta提供本机支持。 一些JavaScript库提供了自己的JSON工具(例如YUI ),但是许多没有(包括jQuery )。
但是,一切都不会丢失-JavaScript是灵活的,只要浏览器需要它们,我们就可以实现JSON stringify和parse方法。
在代码的顶部,我们将创建一个JSON变量,该变量指向本机JSON对象或一个空对象(如果不可用):
var JSON = JSON || {};
JSON.stringify代码稍微复杂一点:
// implement JSON.stringify serialization
JSON.stringify = JSON.stringify || function (obj) {
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") obj = '"'+obj+'"';
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") v = '"'+v+'"';
else if (t == "object" && v !== null) v = JSON.stringify(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
};
如果JSON.stringify不可用,我们定义一个接受单个obj参数的新函数。 该参数可以是单个值,数组或上面的obj1之类的复杂对象。
该代码检查对象类型。 立即返回单个值,并且仅修改字符串以将引号引起来。
如果传递了数组或对象,则代码将遍历每个属性:
- 字符串值添加了引号。
- 子数组或对象将递归传递给JSON.stringify函数。
- 结果值作为“名称:值”字符串或仅数组项的单个值添加到json []数组的末尾。
- 最后,根据需要,将json数组转换为逗号分隔的列表,并在array []或object {}括号内返回。
如果您的大脑感到疼痛,您会很高兴地知道JSON.parse代码要简单得多:
// implement JSON.parse de-serialization
JSON.parse = JSON.parse || function (str) {
if (str === "") str = '""';
eval("var p=" + str + ";");
return p;
};
这将使用eval()将JSON字符串转换为对象。
在着手在所有项目中实现JSON序列化功能之前,有一些陷阱:
- 该代码已故意保留简短。 它在大多数情况下都可以使用,但是与本地JSON.stringify和JSON.parse方法之间存在细微的差异。
- 并非每个JavaScript对象都受支持。 例如,Date()将返回一个空对象,而本机JSON方法会将其编码为日期/时间字符串。
- 该代码将序列化函数,例如var obj1 = {myfunc:function(x){}}; 而原生JSON方法不会。
- 非常大的对象将引发递归错误。
- 在JSON.parse中使用eval()具有内在的风险。 如果您正在调用自己的Web服务,则不会有问题,但是调用第三方应用程序可能会意外或有意破坏您的页面并导致安全问题。 如有必要,可以从json.org获得更安全(但更长或更慢)的JavaScript解析器。
我希望您觉得该代码有用。 随时在自己的项目中使用它。
资源文件:
相关阅读:
即将推出:JSON序列化的有用应用…
From: https://www.sitepoint.com/javascript-json-serialization/