一、问题:
欲将一个JavaScript对象,按如下格式序列化(序列化成字符串):
- 变量名<类型>: [值]
- 变量名<类型>: [值]
- 变量名<类型>: [值]
- 变量名<类型>: [值]
- 变量名<类型>: [值]
- 变量名<类型>: [值]
- prototype<类型>: [值]
- prototype<类型>: [值]
二、解决方案:
首先,定义几个辅助方法:
1. duplicate(): 该方法将给定的字符串复制指定的次数后,与原来的字符串相拼接。
///
/// 复制字符串为原来的n倍
///
String.duplicate = function (s, n) {
var sb = new StringBuffer();
for (var i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
};
2. format(): 该方法按给定的字符串模板与参数列表,合成一个最终的字符串。详细介绍见《给JavaScript的String对象添加一个format方法》:
然后,定义一个辅助类,StringBuffer,用来高效地拼接字符串。
详细介绍见:《JavaScript 版 StringBuffer 类》
最后,递归地序列化指定的对象,源码如下:
///
/// 序列化一个对象(递归地)
///
/// 要被序列化的对象
/// 当前正在被序列化的对象在序列化树中的层级(根级为0)
/// 当前正在被序列化的对象的变量名
///
/// 该方法有四个重载:
/// 1. serializeObject(o);
/// 2. serializeObject(o, level);
/// 3. serializeObject(o, varName);
/// 4. serializeObject(o, level, varName);
///
function serializeObject(){
// 参数列表:
var o = arguments[0];
var level = 0;
var varName = "";
// 重载机制:
switch(typeof arguments[1]){
case "number":
// 重载 2: serializeObject(o, level);
level = arguments[1];
if(arguments.length > 2) {
// 重载 4: serializeObject(o, level, varName);
varName = arguments[2];
}
break;
case "string":
// 重载 3: serializeObject(o, varName);
varName = arguments[1];
break;
default:
// 重载 1: serializeObject(o);
break;
}
var sb = new StringBuffer();
// 根对象信息:
sb.appendLine("{0}{1}<{2}>: [{3}]".format(" ".duplicate(level*2), varName, typeof o, o === null ? "null" : o === undefined ? "undefined" : o.toString()));
// 子对象信息:
switch(typeof o) {
case "object":
for(var i in o){
//sb.appendLine("{0}{1}<{2}>: [{3}]".format(" ".duplicate((level+1)*2), i, typeof o[i], o[i] === null ? "null" : o[i] === undefined ? "undefined" : o[i].toString()));
sb.appendLine(this.serializeObject(o[i], level + 1, i));
} // end for
break;
case "undefined":
break;
default:
// 根对象的prototype信息:
switch(typeof o.prototype){
case "undefined":
break;
default:
sb.appendLine(this.serializeObject(o.prototype, level + 1, "prototype"));
break;
} // end switch (typeof o.prototype)
break;
} // end switch (typeof o)
return sb.toString();
}
完整的代码如下:
; (function () {
if (typeof zizhujy == "undefined") {
zizhujy = {};
window.zizhujy = zizhujy;
}
if (typeof zizhujy.com == "undefined") {
zizhujy.com = {
///
/// 序列化一个对象(递归地)
///
/// 要被序列化的对象
/// 当前正在被序列化的对象在序列化树中的层级(根级为0)
/// 当前正在被序列化的对象的变量名
///
/// 该方法有四个重载:
/// 1. serializeObject(o);
/// 2. serializeObject(o, level);
/// 3. serializeObject(o, varName);
/// 4. serializeObject(o, level, varName);
///
serializeObject: function(){
// 参数列表:
var o = arguments[0];
var level = 0;
var varName = "";
// 重载机制:
switch(typeof arguments[1]){
case "number":
// 重载 2: serializeObject(o, level);
level = arguments[1];
if(arguments.length > 2) {
// 重载 4: serializeObject(o, level, varName);
varName = arguments[2];
}
break;
case "string":
// 重载 3: serializeObject(o, varName);
varName = arguments[1];
break;
default:
// 重载 1: serializeObject(o);
break;
}
var sb = new StringBuffer();
// 根对象信息:
sb.appendLine("{0}{1}<{2}>: [{3}]".format(" ".duplicate(level*2), varName, typeof o, o === null ? "null" : o === undefined ? "undefined" : o.toString()));
// 子对象信息:
switch(typeof o) {
case "object":
for(var i in o){
//sb.appendLine("{0}{1}<{2}>: [{3}]".format(" ".duplicate((level+1)*2), i, typeof o[i], o[i] === null ? "null" : o[i] === undefined ? "undefined" : o[i].toString()));
sb.appendLine(this.serializeObject(o[i], level + 1, i));
} // end for
break;
case "undefined":
break;
default:
// 根对象的prototype信息:
switch(typeof o.prototype){
case "undefined":
break;
default:
sb.appendLine(this.serializeObject(o.prototype, level + 1, "prototype"));
break;
} // end switch (typeof o.prototype)
break;
} // end switch (typeof o)
return sb.toString();
}
};
//
// String Buffer Class
//
function StringBuffer() {
this.__strings__ = new Array();
if (typeof StringBuffer._initialized == "undefined") {
StringBuffer.prototype.append = function (s) {
this.__strings__.push(s);
};
StringBuffer.prototype.appendLine = function (s) {
this.__strings__.push(s + "\n");
};
StringBuffer.prototype.toString = function () {
return this.__strings__.join("");
};
StringBuffer._initialized = true;
}
}
window.StringBuffer = StringBuffer;
String.prototype.format = function () {
// return String.format.apply(arguments);
var string = this;
for (var i = 0; i < arguments.length; i++) {
string = string.replace("{" + i + "}", arguments[i]);
}
return string;
};
///
/// 复制字符串为原来的n倍
///
String.prototype.duplicate = function (n) {
var sb = new StringBuffer();
for (var i = 0; i < n; i++) {
sb.append(this);
}
return sb.toString();
};
}
})();
三、使用示例:
点击这里运行
var o = {
a: 2,
b: 3,
c: {
a: 2,
b: 3,
c: {
a: 1,
b: 2,
c: null,
d: undefined
},
d: function () {
alert("hello");
}
}
};
alert(zizhujy.com.serializeObject(o));
运行结果截图: