自己尝试写的一个小的日志模块,想要实现打印line number的功能。查文档没有看到提供这个功能的api,于是在stackoverflow上找到了一种比较曲线的方法。
Object.defineProperty(global, '__stack', { get: function(){ var orig = Error.prepareStackTrace; Error.prepareStackTrace = function(_, stack){ return stack; }; var err = new Error; Error.captureStackTrace(err, arguments.callee); var stack = err.stack; Error.prepareStackTrace = orig; return stack; } }); Object.defineProperty(global, '__line', { get: function(){ return __stack[1].getLineNumber(); } }); console.log(__line) // line number
我将这段代码放在我的mylog.js模块中, 通过log.info()和log.error()往文件中写入实现log功能
log.info = function(content){ var line_number = __line; //假设这样一行是第20行 var str = makeStr(content, line_number); pushToFile(path, str); } log.error = function(){ //do something }
这里有几个问题,
1.关于__stack这个属性,里面做的处理有点不太明白,我理解思路是在调用__line的地方,强行new一个error,然后根据这个error的内容,通过getLineNumber()方法来获取具体的行数。但是有些处理没有看懂,首先它用orig来保存了之前渲染error的方法Error.prepareStackTrace,然后重新定义了渲染错误的方法并且new了一个error出来,然后保留这个error的stack,并且还原了之前的方法。我每天理解这种做的意义,普通的new一个error出来,不是也应该包含出错行数的信息吗?
2.我在app.js中require了mylog这个模块,但是打印出来的日志,所包含的行数信息,都是__line这个变量在mylog.js中引用的位置。比如上面代码的注释中,假设引用__line的是第20行,那么无论我在app.js中何处打印,都会显示这个行数。显然这不是我想要的结果,我也大概可以想明白原因,想问下有什么方法可以解决这个问题,我只能想到在app.js中使用这个模块时,把__line当参数传入,log.info(content,__line)这样。。但是我觉得集成行数这个功能应该是mylog模块的工作。。请问有什么好的解决办法吗?
闭关修行中......