比如要写一个 JavaScript 的日志输出工具,在方法 log.info() 中能得到调用它所在的文件和代码行号。和众多的日志工具一样,像 log4j,都是在程序代码中主动抛出异常,然后从异常栈中去查找到调用者所在的代码行和文件名。不过也就刚刚才了解到 JavaScript V8 引擎提供了自己的 StackTrace API,Chrome 和 Node.js 可用。先来看可通用的 JavaScript 抛异常 throw new Error() 的方式,下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var log = { info: function(arg){ try { throw new Error(); } catch (e) { alert("Stack:" + e.stack); var loc= e.stack.replace(/Error\n/).split(/\n/)[1].replace(/^\s+|\s+$/, ""); alert("Location: "+loc+""); } } }; function foo(){ log.info(123); } foo(); |
点击链接 http://jsfiddle.net/Unmi/53xas/ 执行,其中是用 document.write() 输出的,完整异常栈是:
1 2 3 4 |
Error at Object.log.info (http://fiddle.jshell.net/_display/:24:19) at foo (http://fiddle.jshell.net/_display/:39:9) at window.onload (http://fiddle.jshell.net/_display/:42:1) |
并且成功定位到调用者代码行是
1 |
Location: Object.log.info (http://fiddle.jshell.net/_display/:24:19) |
上面是在 Chrome 中运行的效果,在 Firefox/Safari 中有所不同,是用 @ 代替了 at,所以在 Fairfox/Safari 中输出的异常栈是
1 2 3 |
window.onload/log.info@http://fiddle.jshell.net/_display/:24 foo@http://fiddle.jshell.net/_display/:39 window.onload@http://fiddle.jshell.net/_display/:42 |
得到代码行
1 |
Location: foo@http://fiddle.jshell.net/_display/:39 |
注意,我都是在 fiddle.jshell.net 上测试我的 JavaScript 代码,fiddle 相当于拿到你的脚本生成一个文件来执行的,所以脚本文件都成了 fiddle 上的某个脚本文件,实际应用中就是你的文件的 URL,比如 special.js。
上面可以稍加改造作为一个简单的日志工具来使用,再辅以传入参数 JSON 序列化 和 Ajax 提交消息到后台,就完整了。
每次想到日志工具,不能不想到各种 log4XX,如 log4j, log4php, log4perl, log4cpp 等不一而足。那么有没有 log4javascript 呢,当然有,那就是 http://log4javascript.org/。这个工具不错,提供了 Popup 或 In-page console 不同颜色级别来显示日志,也可以把日志用 Ajax 发送到后面记录在服务端,并能记录异常,显示出错所在行和文件。
如果你使用的是 V8 引擎,Chrome 和 Node.js 所用的,那么你可以利用 JavaScriptStackTraceApi 来获得行号信息,有两个 API:
Error.captureStackTrace()
Error.prepareStackTrace()
在 Chrome 中可运行下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
var getStackTrace = function() { var obj = {}; Error.captureStackTrace(obj, getStackTrace); return obj.stack; }; function foo(){ return getStackTrace(); } alert("Stack:" + foo()); alert("Location:" + foo().split(/\n+/)[1].replace(/(^\s+|\s+$)/,"")); |
点击链接 http://fiddle.jshell.net/Unmi/EE9gM/ 在 Chrome 中运行类似的代码。在 Firefox/Safari 中得不到结果。
参考:1. JavaScript new Exception(name,message)
2. Javascript中获取出错代码所在文件及行数
本文链接 https://yanbin.blog/javascript-get-execution-line-file/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。