有时我们会忽略错误处理和堆栈追踪的一些细节,但是这些细节对于写与测试或错误处理相关的库来说是非常有用的。例如这周,对于茶就有一个非常棒的公关,该公关极大地改善了我们处理堆栈的方式,当用户的断言失败的时候,我们会给予更多的提示信息(帮助用户进行定位)。
合理地处理堆栈信息能使你清除无用的数据,而只专注于有用的数据。同时,当更好地理解错误对象及其相关属性之后,能有助于你更充分地利用错误。
<强>(函数的)调用栈是怎么工作的强>
在谈论错误之前,先要了解下(函数的)调用栈的原理:
当有一个函数被调用的时候,它就被压入到堆栈的顶部,该函数运行完成之后,又会从堆栈的顶部被移除。
堆栈的数据结构就是后进先出,以后进先出(后进先出)著称。
例如:
函数c () { console.log (' c '); } 函数b () { console.log (b); c (); } 函数(){ console.log (' a '); b (); } (); >之前在上述的示例中,当函数运一行时,其会被添加到堆栈的顶部。然后,当函数b在函数一的内部被调用时,函数b会被压入到堆栈的顶部。当函数c在函数b的内部被调用时也会被压入到堆栈的顶部。
当函数c运行时,堆栈中就包含了a, b和c(按此顺序)。
当函数c运行完毕之后,就会从堆栈的顶部被移除,然后函数调用的控制流就回到函数b。函数b运行完之后,也会从堆栈的顶部被移除,然后函数调用的控制流就回到函数。最后,函数一个运行完成之后也会从堆栈的顶部被移除。
为了更好地在演示中演示堆栈的行为,可以使用console.trace()在控制台输出当前的堆栈数据。同时,你要以从上至下的顺序阅读输出的堆栈数据。
函数c () { console.log (' c '); console.trace (); } 函数b () { console.log (b); c (); } 函数(){ console.log (' a '); b (); } (); >之前在节点的REPL模式中运行上述代码会得到如下输出:
跟踪 在c (repl: 3:9) 在b (repl: 3:1) 在一个(repl: 3:1) 在repl: 1:1//& lt;——现在请忽略任何低于这一点,这些节点的内部 realRunInThisContextScript (vm.js 22:35): sigintHandlersWrap (vm.js 98:12): ContextifyScript.Script.runInThisContext (vm.js:书》第24章12节) REPLServer.defaultEval (repl.js 313:29): 在绑定(domain.js 280:14): 在REPLServer.runBound (eval) (domain.js 293:12): >之前正如所看到的,当从函数c中输出时,堆栈中包含了函数,以b及c。
如果在函数c运行完成之后,在函数b中输出当前的堆栈数据,就会看到函数c已经从堆栈的顶部被移除,此时堆栈中仅包括函数a和b。
函数c () { console.log (' c '); } 函数b () { console.log (b); c (); console.trace (); } 函数(){ console.log (' a '); b (); } >之前正如所看到的,函数c运行完成之后,已经从堆栈的顶部被移除。
跟踪 在b (repl: 9) 在一个(repl: 3:1) 在repl: 1:1//& lt;——现在请忽略任何低于这一点,这些节点的内部 realRunInThisContextScript (vm.js 22:35): sigintHandlersWrap (vm.js 98:12): ContextifyScript.Script.runInThisContext (vm.js:书》第24章12节) REPLServer.defaultEval (repl.js 313:29): 在绑定(domain.js 280:14): 在REPLServer.runBound (eval) (domain.js 293:12): 在REPLServer。在线(repl.js 513:10): >之前<强>错误对象和错误处理强>
当程序运行出现错误时,通常会抛出一个错误对象。误差对象可以作为用户自定义错误对象继承的原型。
错误。原型对象包含如下属性:
——指向实例的构造函数
——错误信息
——错误的名字(类型)
上述是错误。原型的标准属性,此外,不同的运行环境都有其特定的属性。在例如节点,Firefox、Chrome,边缘,IE 10 +,歌剧以及Safari 6 +这样的环境中,误差对象具备堆栈属性,该属性包含了错误的堆栈轨迹。一个错误实例的堆栈轨迹包含了自构造函数之后的所有堆栈结构。
JavaScript错误处理和堆栈追踪详解