/** * @fileoverview オブジェクトのダンプを文字列として出力する。 * Firefox4.0, Google Chrome11, Internet Explorer8でテスト済。 * 参考にしたソース: http://d.hatena.ne.jp/Climber/20070619/1182247305 * @author mimami24im@gmail.com */ /** * @namespace */ var midump = {}; /* 定数 */ midump.con = { maxDepth: 10, // 再帰する深さの最大値 br: { // 改行文字 text: '\n', html: '
' }, indent: { // インデント文字 text: ' ', html: '  ' }, funcstr: 'function(){}' // メンバがfunctionの場合出力される文字列 }; /* グローバル変数 */ midump.dec = 0; // numberを四捨五入する桁 - 1。四捨五入しない場合はnull midump.linear = false; // linearモードの場合はtrue midump.brstr = ''; // 改行文字 midump.indentstr = ''; // インデント文字 midump.dispf = false; // objectのmethodを出力する場合はtrue midump.escape = false; // 制御文字、ダブルクォートをエスケープする場合はtrue /** * オブジェクトのダンプを出力する * @param {Object} obj ダンプ対象オブジェクト * @param {?number} dec numberを小数点以下何桁で四捨五入するか。 * 四捨五入しない場合はnull * @param {boolean} linear 改行およびインデントせず、 * objectのmethodを出力しない場合true。それ以外の場合false * @param {boolean} escape 制御文字、ダブルクォートをエスケープする場合はtrue。 * それ以外の場合false。nullの場合のデフォルト値はture。 * linear == true の場合、 * ダブルクォートではなくシングルクォートがエスケープされる。 * @param {?{html: boolean, dispf: boolean}} opt * html: 改行を'
',スペースを' 'で出力する場合true。 * 改行を'\n',スペースを' 'で出力する場合false * dispf: objectのmethodを出力する場合true。それ以外の場合false * nullの場合のデフォルト値は全てtrueだが、linearの値が優先される。 * @return {string} ダンプ結果 */ midump.objdump = function(obj, dec, linear, escape, opt) { midump.init_(); if (dec === null) { midump.dec = null; } else if (isNaN(dec) || dec < 1) { midump.dec = 0; } else { midump.dec = ~~dec - 1; } if (linear) { midump.linear = true; midump.brstr = ''; midump.dispf = false; } else { if (opt && opt.html === false) { midump.brstr = midump.con.br.text; midump.indentstr = midump.con.indent.text; } else { midump.brstr = midump.con.br.html; midump.indentstr = midump.con.indent.html; } if (opt && opt.dispf === false) { midump.dispf = false; } else { midump.dispf = true; } } if (escape === false) { midump.escape = false; } else { midump.escape = true; } var dumpstr = midump.dump_(obj, 0); if (midump.linear) { dumpstr = '\'' + dumpstr + '\''; } return dumpstr; }; /** * 初期処理 * @private */ midump.init_ = function() { // グローバル変数初期化 midump.dec = 0; midump.linear = false; midump.brstr = ''; midump.indentstr = ''; midump.dispf = false; midump.escape = false; }; /** * オブジェクトのダンプを出力する * @param {Object} obj ダンプ対象オブジェクト * @param {number} depth 現在の再帰の深さ * @return {string} ダンプ結果 * @private */ midump.dump_ = function(obj, depth) { if (depth >= midump.con.maxDepth) { throw 'depth over ' + midump.con.maxDepth; } if (obj === null) return 'null'; switch (typeof obj) { case 'undefined': return 'undefined'; case 'boolean': return obj ? 'true' : 'false'; case 'function': return midump.con.funcstr; case 'string': if (midump.escape) { return '\"' + midump.escape_(obj) + '\"'; } else { return '\"' + obj + '\"'; } case 'number': if (midump.dec === null) { return obj; } else { return midump.round_(obj); } case 'object': var str = []; if (obj instanceof Array) { for (var i = 0; i < obj.length; i++) { str.push(midump.dump_(obj[i], depth + 1)); } var joinstr = ''; if (obj.length > 0) { joinstr = midump.indent_(depth + 1) + str.join(',' + midump.indent_(depth + 1)) + midump.indent_(depth); } var rtnstr = '[' + joinstr + ']'; return rtnstr; } else { var props = []; for (var prop in obj) { props.push(prop); } props.sort(); var probval; for (var i = 0; i < props.length; i++) { probval = midump.dump_(obj[props[i]], depth + 1); if (probval == midump.con.funcstr && !midump.dispf) { continue; } else { str.push(props[i] + ':' + probval); } } var joinstr = ''; if (props.length > 0) { joinstr = midump.indent_(depth + 1) + str.join(',' + midump.indent_(depth + 1)) + midump.indent_(depth); } var rtnstr = '{' + joinstr + '}'; return rtnstr; } } return obj; }; /** * インデント文字列を作成する。 * @param {number} depth インデントする深さ。インデントしない場合0 * @return {string} インデント文字列 * @private */ midump.indent_ = function(depth) { var str = midump.brstr; if (midump.indentstr != '') { for (i = 0; i < depth; i++) { str += midump.indentstr; } } return str; }; /** * 四捨五入する * @param {number} num 対象となる値 * @return {number} 四捨五入した結果 * @private */ midump.round_ = function(num) { // 浮動小数点の誤差対策で、小さい値を足している var temp = (num + 1 / Math.pow(10, midump.dec + 5)) * Math.pow(10, midump.dec); temp = Math.round(temp); temp /= Math.pow(10, midump.dec); return temp; }; // エスケープ用正規表現文字列 midump.repArr = [[/\\/g,'\\\\'], [/\n/g,'\\n'], [/\r/g ,'\\r'], [/\t/g,'\\t']]; midump.repSq = [/(')/g,'\\$1']; midump.repDq = [/(")/g,'\\$1']; /** * 制御文字、クォートをエスケープする * @param {string} str エスケープ対象文字列 * @return {string} エスケープした結果 * @private */ midump.escape_ = function(str) { for(var i = 0; i < midump.repArr.length; i++) { str = str.replace.apply(str, midump.repArr[i]); } if (midump.linear) { // linearモードの場合は出力全体をシングルクォートで囲うため、 // シングルクォートをエスケープする str = str.replace.apply(str, midump.repSq); } else { str = str.replace.apply(str, midump.repDq); } return str; };