Error.prototype.stack

非标准
该特性是非标准的,请尽量不要在生产环境中使用它!

Error对象作为一个非标准的栈属性提供了一种函数追踪方式。无论这个函数被被调用,处于什么模式,来自于哪一行或者哪个文件,有着什么样的参数。这个栈产生于最近一次调用最早的那次调用,返回原始的全局作用域调用

描述

每个步骤都会被分为单独的一行以这个函数的名字作为开始(如果不是一个来自于全局作用域的调用),然后通过一个@符号标记一个文件的位置(尤其是当一个函数构造错误并且作为错误被抛出,并且如果能定位到这个文件的位置,那么会使用冒号显示行号。(提示)Error对象在错误跑出时同样能处理并渲染出文件名,行号和列号属性(但是仅仅限于错误。而不是追踪他的路径)

注意这是Firefox定义的格式,并没有标准的定义。但是Safari 6+ 和 Opera 12-定义了一种非常相似的格式。其他使用JavaScript V8引擎的浏览器(例如Chrome, Opera 15+,安卓浏览器)和IE 10+,定义了一种不同的格式(可参见 error.stack 文档)

堆栈中的参数值: Firefox 14版本之前是 (bug 744842)函数名会随着参数值会在添加@符号之前被立即转换成用圆括号包裹的string类型。然而对象或者数组等其他类型似乎会被转换成"[object Object]"并且这种格式不能回退到之前实际上的对象,而纯值会被渲染(或许这种在Firefox14中仍有这种可能,使用arguments.callee.caller.arguments更加简单。因为函数名可以使用arguments.callee.caller.name渲染)。"undefined"被显示为"(void 0)"不过要注意的是如果是字符串类型的参数会直接以类似"@", "(", ")"格式通过编译(或者是包含在文件名中)。你不能简单的依赖这些将它分成多个组件,但是,对于Firefox14及以后的版本来说,这些都不是问题

不同的浏览器会在不同时期设置这个值。例如,Firefox在创建Error时, 并且MSDN docs 似乎也实现了PhantomJS的方式。

示例

下面这段html代码展示了stack 属性的使用方法

<!DOCTYPE HTML>
<meta charset="UTF-8">
<title>Stack Trace Example</title>
<body>
<script>
function trace() {
  try {
    throw new Error('myError');
  }
  catch(e) {
    alert(e.stack);
  }
}
function b() {
  trace();
}
function a() {
  b(3, 4, '\n\n', undefined, {});
}
a('first call, firstarg');
</script>

假设上面这段代码被保存在Windows系统下的 C:\example.html在处理过程中抛出如下所示的错误信息

Firefox 30及以上版本的浏览器会包含以列号为开始 (bug 762556):

trace@file:///C:/example.html:9:17
b@file:///C:/example.html:16:13
a@file:///C:/example.html:19:13
@file:///C:/example.html:21:9

Firefox 14 to Firefox 29:

trace@file:///C:/example.html:9
b@file:///C:/example.html:16
a@file:///C:/example.html:19
@file:///C:/example.html:21

Firefox 13及更早版本的浏览器会抛出如下信息:

Error("myError")@:0
trace()@file:///C:/example.html:9
b(3,4,"\n\n",(void 0),[object Object])@file:///C:/example.html:16
a("first call, firstarg")@file:///C:/example.html:19
@file:///C:/example.html:21

Stack of eval'ed code

Firefox30以(Firefox 30 / Thunderbird 30 / SeaMonkey 2.27 / Firefox OS 1.4)格式开头,Function() 和 eval() 调用产生的错误代码堆栈,现在在调用内部通过行号和列号以更加详细的格式向我们展示出来。函数调用显示为"> Function" 而 eval调用则是 "> eval"这样。下面来看这个bug 332176.

try {
  new Function('throw new Error()')();
} catch (e) {
  console.log(e.stack);
}

// anonymous@file:///C:/example.html line 7 > Function:1:1
// @file:///C:/example.html:7:6


try {
  eval("eval('FAIL')");
} catch (x) {
  console.log(x.stack);
}

// @file:///C:/example.html line 7 > eval line 1 > eval:1:1
// @file:///C:/example.html line 7 > eval:1:1
// @file:///C:/example.html:7:6

你也可以使用//# sourceURL 命名eval源的指令。 也可以查看在 Debugger文档中的Debug eval 源blog post博客 。

规范

不属于任何规范,没有标准规范。

浏览器兼容性

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
stack
Non-standard
Chrome Full support 3 Edge Full support 12 Firefox Full support 1 IE Full support 10 Opera Full support Yes Safari Full support 6 WebView Android Full support ≤37 Chrome Android Full support 18 Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support 6 Samsung Internet Android Full support 1.0 nodejs Full support Yes

Legend

Full support  
Full support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.

另请参阅