JavaScript 更改控制台调用堆栈
JavaScript Change console call stack
正确的行为
当我直接从一个函数调用 console.log()
时,我调用的堆栈(函数和文件)在开发工具控制台中是正确的,正如预期的那样。
main.js
:
function main() {
// Works correctly
console.log('Hello from main()!');
}
控制台:
Hello from main()! ... main.js:3
我想要什么
现在,当我添加第二个名为 debug.js
的文件并从那里调用 console.log
时,我调用的文件是 debug.js
,这是正确的...但是我需要 debug()
才能像在 main.js
中调用一样进行记录。我需要以某种方式修改调用者、堆栈或跟踪以欺骗 console.log()
它是从 main.js
调用的,而实际上它是从 deubg.js
.
代码
debug.js
:
function debug(msg) {
console.log(msg)
}
main.js
function main() {
debug('Hello world!') // debug() in debug.js
}
行为
当前行为:
Hello world! ... debug.js:2
我想要的行为:
Hello world! ... main.js:3
正如 WHATWG specification 所说,每个功能(错误、警告、日志等)的控制台输出都是特定于实现的:
The printer operation is implementation-defined
碰巧,基于 chromium 的浏览器在打印 console.log
的结果时显示调用堆栈的当前 帧 (不是完整的调用堆栈),你赢了' 能够更改此行为,因为这与 JavaScript 引擎相关(V8 用于基于铬的浏览器),并且无法通过 JavaScript 代码进行自定义。
唯一允许您显示完整调用堆栈的 JavaScript 标准是 console.trace
whose specification is here: https://console.spec.whatwg.org/#trace
它会为您的示例代码显示如下内容:
这可以通过创建 Error 实例 new Error()
来完成,它将以字符串形式保存跟踪,如下所示。
function debug(...args) {
const error = new Error();
console.log(...args, error.stack.replace(/.+\n.+\n/, ''))
}
尽管MDN Error stack document says it's a non standard property but seems all browser has support for that Browser compatibility
我认为这里的问题是控制台日志通常是从它运行的任何地方执行的。但是,如果您要传回执行控制台日志的函数,这可能会如您所愿。你能试试下面的代码吗?
尝试 #1
debug.js:
function debug(msg) {
return (function(msg) { console.log(msg) })(msg)
}
main.js:
function main() {
debug('Hello world!')
}
如果还是不行,你可以试试这个吗:
尝试#2
debug.js:
function debug() {
return function(msg) { console.log(msg) }
}
main.js:
function main() {
debug()('Hello world!')
}
您可以做的是:
const log = console.log // for future use, preserve the default function
console.log = (...args) => {
console.trace(...args)
}
在节点上:
console.log = (...args) => {
console.trace(...args, path.basename(__filename))
}
要得到这样的东西:
const path = require("path");
console.log = (...args) => {
console.trace(...args, path.basename(__filename))
}
function f() {
return function g() {
console.log("test")
}
}
f()()
正确的行为
当我直接从一个函数调用 console.log()
时,我调用的堆栈(函数和文件)在开发工具控制台中是正确的,正如预期的那样。
main.js
:
function main() {
// Works correctly
console.log('Hello from main()!');
}
控制台:
Hello from main()! ... main.js:3
我想要什么
现在,当我添加第二个名为 debug.js
的文件并从那里调用 console.log
时,我调用的文件是 debug.js
,这是正确的...但是我需要 debug()
才能像在 main.js
中调用一样进行记录。我需要以某种方式修改调用者、堆栈或跟踪以欺骗 console.log()
它是从 main.js
调用的,而实际上它是从 deubg.js
.
代码
debug.js
:
function debug(msg) {
console.log(msg)
}
main.js
function main() {
debug('Hello world!') // debug() in debug.js
}
行为
当前行为:
Hello world! ... debug.js:2
我想要的行为:
Hello world! ... main.js:3
正如 WHATWG specification 所说,每个功能(错误、警告、日志等)的控制台输出都是特定于实现的:
The printer operation is implementation-defined
碰巧,基于 chromium 的浏览器在打印 console.log
的结果时显示调用堆栈的当前 帧 (不是完整的调用堆栈),你赢了' 能够更改此行为,因为这与 JavaScript 引擎相关(V8 用于基于铬的浏览器),并且无法通过 JavaScript 代码进行自定义。
唯一允许您显示完整调用堆栈的 JavaScript 标准是 console.trace
whose specification is here: https://console.spec.whatwg.org/#trace
它会为您的示例代码显示如下内容:
这可以通过创建 Error 实例 new Error()
来完成,它将以字符串形式保存跟踪,如下所示。
function debug(...args) {
const error = new Error();
console.log(...args, error.stack.replace(/.+\n.+\n/, ''))
}
尽管MDN Error stack document says it's a non standard property but seems all browser has support for that Browser compatibility
我认为这里的问题是控制台日志通常是从它运行的任何地方执行的。但是,如果您要传回执行控制台日志的函数,这可能会如您所愿。你能试试下面的代码吗?
尝试 #1
debug.js:
function debug(msg) {
return (function(msg) { console.log(msg) })(msg)
}
main.js:
function main() {
debug('Hello world!')
}
如果还是不行,你可以试试这个吗:
尝试#2
debug.js:
function debug() {
return function(msg) { console.log(msg) }
}
main.js:
function main() {
debug()('Hello world!')
}
您可以做的是:
const log = console.log // for future use, preserve the default function
console.log = (...args) => {
console.trace(...args)
}
在节点上:
console.log = (...args) => {
console.trace(...args, path.basename(__filename))
}
要得到这样的东西:
const path = require("path");
console.log = (...args) => {
console.trace(...args, path.basename(__filename))
}
function f() {
return function g() {
console.log("test")
}
}
f()()