一、问题:
欲将一个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));
运行结果截图: