入力した変数名のオブジェクトのプロトタイプを全て表示する
Last active
March 19, 2018 23:39
-
-
Save sounisi5011/1c94e9ce21848e30678ab47ba03b4f54 to your computer and use it in GitHub Desktop.
入力した変数名のオブジェクトのプロトタイプを全て表示するデバッグ用ページ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset=utf-8> | |
<meta name=viewport content="width=device-width,initial-scale=1"> | |
<meta name=format-detection content="telephone=no,email=no,address=no"> | |
<title>入力した変数名のオブジェクトのプロトタイプを全て表示するデバッグ用ページ</title> | |
<link rel=stylesheet href=main.css> | |
<div id=main></div> | |
<h2>Gist</h2> | |
<a href=https://gist.github.com/sounisi5011/1c94e9ce21848e30678ab47ba03b4f54>https://gist.github.com/sounisi5011/1c94e9ce21848e30678ab47ba03b4f54</a> | |
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es5,caniuse:console-basic&flags=always,gated" crossorigin=anonymous></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/hyperapp/1.2.0/hyperapp.js" integrity="sha256-nGvSTSqpX5gJdp7Jv5+4FCU1IbclUByINJqDQIbfwNc=" crossorigin=anonymous></script> | |
<script src=main.js></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pre { | |
overflow: auto; | |
} | |
.error { | |
color: red; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MAX_SHOW_PROP_LENGTH = 6; | |
var MAX_STR_LENGTH = 200; | |
var MAX_SYMPLE_STR_LENGTH = 100; | |
var h = hyperapp.h; | |
var app = hyperapp.app; | |
/** | |
* 値を見やすい文字列表記に変換する | |
* @param {*} value 対象の値 | |
* @param {boolean=} simple trueを指定した場合、表記を簡略化する | |
*/ | |
var showValueData = function() { | |
/** | |
* @see https://stackoverflow.com/a/6969486/4907315 | |
*/ | |
var escapeRegExp = function(str) { | |
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
}; | |
var getObjectName = function(obj) { | |
var objStr = Object.prototype.toString.call(obj); | |
var match = /^\[object\s+([^\s\[\]]+)\s*\]$/i.exec(objStr); | |
return match ? match[1] : "[unknown object: " + objStr + "]"; | |
}; | |
var getDetails = function(value, simple) { | |
var varType = typeof value; | |
switch (varType) { | |
case "undefined": | |
return "undefined"; | |
case "boolean": | |
case "number": | |
case "symbol": | |
return String(value); | |
case "string": | |
var maxLen = MAX_STR_LENGTH; | |
if (simple) { | |
maxLen = MAX_SYMPLE_STR_LENGTH; | |
value = value.replace(/\r\n?|\n/g, " "); | |
} | |
return ( | |
'"' + | |
value.substr(0, maxLen) + | |
(maxLen < value.length ? "…" : "") + | |
'"' | |
); | |
case "function": | |
var name = getObjectName(value); | |
var funcStr = String(value) | |
.replace(/^(\s*)function(\s)/, "$1f$2"); | |
var maxLen = MAX_STR_LENGTH; | |
if (simple) { | |
maxLen = MAX_SYMPLE_STR_LENGTH; | |
funcStr = funcStr.replace(/\s{2,}|\r\n?|\n/g, " "); | |
} | |
return ( | |
funcStr.substr(0, maxLen) + | |
(maxLen < funcStr.length ? funcStr.replace(/(\}\s*)?$/, "…$&") : "") | |
); | |
case "object": | |
if (value === null) { | |
return "null"; | |
} else { | |
var outputTextList = []; | |
if (simple) { | |
var name = getObjectName(value); | |
if (name !== "Object") { | |
return name + " {…}"; | |
} else { | |
return "{…}"; | |
} | |
} else { | |
for (var proto = value; proto; proto = Object.getPrototypeOf(proto)) { | |
var name = getObjectName(proto); | |
var propList = Object.getOwnPropertyNames(proto); | |
outputTextList.push( | |
name + " {" + ( | |
propList | |
// .slice(0, MAX_SHOW_PROP_LENGTH) | |
.map(function(propName) { | |
try { | |
var valueStr = getDetails(proto[propName], true); | |
} catch(e) { | |
console.error(e); | |
return propName + ": (...)"; | |
} | |
return propName + ": " + ( | |
valueStr | |
.replace(new RegExp("^(f(?:unction)?\\s+)" + escapeRegExp(propName) + "(\\s*\\()"), "$1..$2") | |
); | |
}) | |
// .concat(MAX_SHOW_PROP_LENGTH < propList.length ? ["…"] : []) | |
.join(", ") | |
) + "}" | |
); | |
} | |
return outputTextList.join("\n "); | |
} | |
} | |
break; | |
default: | |
return "unknown type [" + varType + "]"; | |
} | |
}; | |
return function(value, simple) { | |
console.groupCollapsed("showValueData()"); | |
var ret = getDetails(value, simple); | |
console.groupEnd(); | |
return ret; | |
}; | |
}(); | |
var state = { | |
value: undefined, | |
details: "", | |
error: undefined | |
}; | |
var actions = { | |
showDetails: function(varName) { | |
return function(state, actions) { | |
try { | |
var value = Function("return " + varName + ";")(); | |
var detailsText = showValueData(value); | |
return { | |
value: value, | |
details: detailsText, | |
error: undefined | |
}; | |
} catch(e) { | |
return { | |
value: undefined, | |
details: "", | |
error: e | |
}; | |
} | |
}; | |
} | |
}; | |
var view = function(state, actions) { | |
var err = state.error; | |
return h("p", {}, [ | |
h("input", { | |
type: "text", | |
placeholder: "変数名を入力…" | |
}), | |
h("input", { | |
type: "button", | |
value: "表示", | |
onclick: function(e) { | |
return actions.showDetails(e.target.previousSibling.value); | |
} | |
}), | |
h("pre", err ? {class: "error"} : {}, ( | |
err ? | |
(err.name + ": " + err.message) : | |
(state.details) | |
)) | |
]); | |
}; | |
app(state, actions, view, document.getElementById("main")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment