JavaScript错误处理和堆栈追踪详解

  

有时我们会忽略错误处理和堆栈追踪的一些细节,但是这些细节对于写与测试或错误处理相关的库来说是非常有用的。例如这周,对于茶就有一个非常棒的公关,该公关极大地改善了我们处理堆栈的方式,当用户的断言失败的时候,我们会给予更多的提示信息(帮助用户进行定位)。

  

合理地处理堆栈信息能使你清除无用的数据,而只专注于有用的数据。同时,当更好地理解错误对象及其相关属性之后,能有助于你更充分地利用错误。

  

<强>(函数的)调用栈是怎么工作的

  

在谈论错误之前,先要了解下(函数的)调用栈的原理:

  

当有一个函数被调用的时候,它就被压入到堆栈的顶部,该函数运行完成之后,又会从堆栈的顶部被移除。

  

堆栈的数据结构就是后进先出,以后进先出(后进先出)著称。

  

例如:         函数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错误处理和堆栈追踪详解