/** * Json對象操作,增刪改查 * * @author lellansin * @blog www.lellansin.com * @version 0.1 * * 解決一些常見的問題 * get/set 解決獲取和設置時,無節點中斷的問題 * create 可以創建多級節點,若存在則覆蓋新值 * delete 刪除節點及其子節點 * print_r 格式化輸出對象(調試用) * 實例見底部 */ function Json() { } /** * 獲取Json對象中的某個節點 * 例如:json.get(Data, 'country', 'province', 'city'); * 結果則返回 Data['country']['province']['city'] * 無則返回false */ Json.prototype.get = function(obj, key) { var args = this.get.arguments; var result = obj; for (var i = 1; i < args.length; i++) { result = result[args[i]]; if (result === undefined) { return false; }; }; return result; }; /** * 設置Json對象中的某個節點 * 例如:obj.set(data, "ENTRY", "FA_TOKEN_INVALID", 1234); * 將 data['ENTRY']['FA_TOKEN_INVALID'] 設置為1234 * 成功true, 失敗false */ Json.prototype.set = function(obj, key) { var args = this.set.arguments; if (ergodic_set(obj, args, 1)) { return true; } else { return false; } } /** * 在Json對象中創建節點(若存在則覆蓋值) * 例如:obj.create(data, 'add', 'hello', 'test', 120); * 添加 data['create']['hello']['test'] 節點並設置值為 120 * 成功true, 失敗false */ Json.prototype.create = function(obj, key) { var args = this.create.arguments; if (ergodic_create(obj, args, 1)) { return true; } else { return false; } } /** * 在Json對象中刪除節點 * 例如:obj.delete(prods, 'grade', 'math'); * 成功true, 失敗false */ Json.prototype.delete = function(obj, key) { var args = this.delete.arguments; if (ergodic_delete(obj, args, 1)) { return true; } else { return false; } } /** * 返回Json對象的字符串形式(封裝 ECMAScript 庫函數) */ Json.prototype.getStr = function(obj) { return JSON.stringify(obj); } /** * 解析字符串返回Json對象(封裝 ECMAScript 庫函數) */ Json.prototype.getJson = function(str) { return JSON.parse(str); } /** * 格式化輸出Json對象 */ Json.prototype.print_r = function(obj) { console.log("{") ergodic_print(obj, ""); console.log("}") } function ergodic_print(obj, indentation) { var indent = " " + indentation; if (obj.constructor == Object) { for (var p in obj) { if (obj[p].constructor == Array || obj[p].constructor == Object) { console.log(indent + "[" + p + "] => " + typeof(obj) + ""); console.log(indent + "{"); ergodic_print(obj[p], indent); console.log(indent + "}"); } else if (obj[p].constructor == String) { console.log(indent + "[" + p + "] => '" + obj[p] + "'"); } else { console.log(indent + "[" + p + "] => " + obj[p] + ""); } } } } function ergodic_set(obj, args, floor) { if (obj.constructor == Object) { for (var tmpKey in obj) { if (tmpKey == args[floor]) { if (floor < args.length - 2) { return ergodic_set(obj[tmpKey], args, floor + 1); } else { // 此時參數floor為倒數第二個,加1值為最后一個 obj[tmpKey] = args[floor + 1]; console.log("成功設置,返回true"); return true; } } } } } function ergodic_create(obj, args, floor) { if (obj.constructor == Object) { for (var tmpKey in obj) { if (tmpKey == args[floor]) { if (floor < args.length - 2) { return ergodic_create(obj[tmpKey], args, floor + 1); } else { obj[tmpKey] = args[floor + 1]; return true; } } } } // 節點不存在,創建新節點 if (floor < args.length - 1) { var jsonstr = getJsonFormat(args[args.length - 1]); for (var i = args.length - 2; i > floor; i--) { jsonstr = '{"' + args[i] + '":' + jsonstr + '}'; }; // 使用eval解析第三方Json數據時,可能會執行惡意代碼 // var node = eval('(' + jsonstr + ')'); var node = JSON.parse(jsonstr); obj[args[floor]] = node; return true; } } function ergodic_delete(obj, args, floor) { if (obj.constructor == Object) { for (var tmpKey in obj) { if (tmpKey == args[floor]) { if (floor < args.length - 1) { return ergodic_delete(obj[tmpKey], args, floor + 1); } else { delete obj[tmpKey]; return true; } } } } } function getJsonFormat(param) { if (param.constructor == String) { return '"' + param + '"'; } else { return param; } } /** * 使用實例 */ var data = { OK: 200, FAIL: 500, ENTRY: { FA_TOKEN_INVALID: 1001, FA_TOKEN_EXPIRE: 1002, FA_USER_NOT_EXIST: 1003 }, GATE: { FA_NO_SERVER_AVAILABLE: 2001 }, CHAT: { FA_CHANNEL_CREATE: 3001, FA_CHANNEL_NOT_EXIST: 3002, FA_UNKNOWN_CONNECTOR: 3003, FA_USER_NOT_ONLINE: 3004 } }; var json = new Json(); console.log("獲取Json中節點"); console.log(json.get(data, "OK")); // 200 console.log(json.get(data, "ENTRY", "FA_TOKEN_INVALID")); // 1001 console.log(json.get(data, "TEST", "獲取沒有的節點")); // false 沒有的節點返回 false console.log("設置Json中節點"); console.log(json.set(data, "ENTRY", "FA_TOKEN_INVALID", 1234)); // true 設置成功 console.log(json.get(data, "ENTRY", "FA_TOKEN_INVALID")); // 1234 獲取剛設置的節點 console.log(json.set(data, "ENTRY", "測試設置沒有的節點", 1234)); // false 設置失敗 console.log("創建新的Json節點"); var prods = { 'name': 'Alan', 'grade': { 'Chinese': 120, 'math': 130, 'competition': { 'NOI': 'First prize' } } }; console.log(json.create(prods, 'create', 'hello', 'test', 120)); // true console.log(json.create(prods, 'create', 'hello', 'test2', '通過')); // true console.log("格式化輸出節點"); json.print_r(prods); console.log("刪除節點"); console.log(json.delete(prods, 'grade', 'math')); // true console.log(json.delete(prods, 'grade', 'competition')); // true console.log(json.delete(prods, 'grade', '刪除沒有的節點')); // false json.print_r(prods);