`throw new Error`和`throw someObject`有什么区别?


378

我想编写一个通用的错误处理程序,它将捕获在任何代码实例上故意抛出的自定义错误。

当我throw new Error('sample')喜欢以下代码时

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

日志在Firefox中显示为,Error: [object Object]而我无法解析该对象。

对于第二个throw日志,显示为:Error: hehe

我什么时候做

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

控制台显示为:Object { hehe="haha"}在其中可以访问错误属性。

有什么区别?

代码中有区别吗?像字符串一样,只是作为字符串传递,而像对象一样传递,但是语法会有所不同吗?

我没有探索过抛出错误对象……我只做过抛出字符串。

除上述两种方法外,还有其他方法吗?


6
抛出新的Error({prop:val})的问题是那不是Error的有效构造。错误具有Hemant讨论的已知属性。
Grantwparks 2013年

Answers:


216

这是有关The Error对象并引发您自己的错误的很好的解释

错误对象

如果发生错误,我们可以从中提取出什么?所有浏览器中的Error对象都支持以下两个属性:

  • name:错误的名称,或更具体地说,错误所属的构造函数的名称。

  • 消息:错误的描述,该描述因浏览器而异。

name属性可以返回六个可能的值,如上所述,它们对应于错误的构造函数的名称。他们是:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

抛出自己的错误(异常)

您无需等待控制权从try块自动转移到catch块之前发生6种错误中的一种,您还可以显式地抛出自己的异常以强制按需发生。这对于创建自己的错误定义以及何时应该转移控制权来捕获是非常有用的。


4
哦,是的。这是我问这个问题之前想念的一件好事。无论如何,搜索与此相关信息的用户将被清除。现在我清楚什么是什么。:) 谢谢。我将在几天后重新投票。
Jayapal Chandran 2012年

184
甚至没有回答这个问题,但还是最受支持的答案?
user9993

@ user9993当时用户提出的问题是希望根据每次聊天进行详细的了解,因此相应地提供了答案并对用户有用。这就是接受和最多投票的原因。
Hemant Metalia

5
@HemantMetalia但是他是对的,答案显示出甚至没有丝毫尝试回答OP的问题。如果在聊天中回答了一些非常不同的答案而应该保留在聊天中,则这里的问题和答案没有逻辑联系。
Mörre

并且要回答原始问题,对Javascript没关系。但是,Error(和子类)按惯例使用。默认情况下,它们还提供stack属性,尽管可以手动将其添加到其他属性。因此,实际上,这在大多数情况下都是惯例,程序流程不受您所抛出的内容的影响,而仅仅是您throw的所有事项。您可以throw "grandmother down the stairs";并且它的工作原理相同,只是没有附加的堆栈跟踪和错误处理功能,报告器,调试器期望Error或附带的属性更加精确。
Mörre

104

扔“我是邪恶的”

throw终止进一步执行并在捕获错误时公开消息字符串 。

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

抛出后的控制台将永远不会终止。


抛出新的错误(“我好可爱”)

throw new Error使用两个参数名称消息公开一个错误事件。它还终止进一步执行

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}


16
“ throw Error('whatever')”和“ throw new Error('whatever')”之间的区别怎么样-都可以。
joedotnot

9
错误是功能,新错误是构造函数。这两个作品相同的 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Nishchit Dhanani

5
@NishchitDhanani我感到奇怪的是,如此难以理解和错误的评论遭到了投票。“错误是功能性的”或“新错误是构造函数”都没有任何意义和/或错误。在那种情况下,不清楚该链接应该“证明”的确切位置。这是MDN的页面Error,好的,评论的连接在哪里?评论和回答OP问题的一半人应该保持沉默。
Mörre

@Mörre请参阅本节Used as a function从这个链接... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Nishchit Dhanani

知道了 这是一个功能
Nishchit Dhanani

73

下面的文章也许会更详细地说明哪个是更好的选择。throw 'An error'throw new Error('An error')

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

这表明后者(new Error())更可靠,因为使用Internet Explorer和Safari(不确定版本)之类的浏览器在使用前者时无法正确报告该消息。

这样做会引发错误,但是并非所有浏览器都会以您期望的方式响应。Firefox,Opera和Chrome均显示“未捕获的异常”消息,然后包含消息字符串。Safari和Internet Explorer只会引发“未捕获的异常”错误,根本不提供消息字符串。显然,从调试的角度来看,这是次优的。


36

您首先提到此代码:

throw new Error('sample')

然后在第一个示例中,您将编写:

throw new Error({'hehe':'haha'}) 

第一个Error对象实际上将起作用,因为它需要一个字符串值,在这种情况下为'sample'。第二个原因不是因为您试图传入一个对象,而是期望一个字符串。

错误对象将具有“ message”属性,该属性为“ sample”。


12
第二个确实起作用,只是不是以非常有用的方式。它对toString()传入的对象执行该方法,从而导致[object Object]错误(如Op所写)。
cjn


15

你可以throw作为对象

throw ({message: 'This Failed'})

然后例如在您的 try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

或者只是抛出一个字符串错误

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string

15

Error构造函数用于创建一个错误对象。发生运行时错误时,将引发错误对象。Error对象也可以用作用户定义的异常的基础对象。

通过该throw语句引发用户定义的错误。程序控制将传递到catch调用堆栈中的第一个块。

有错误对象和无错误对象时抛出错误的区别:


throw {'hehe':'haha'};

在chrome devtools中看起来像这样:

在此处输入图片说明

Chrome告诉我们,我们有一个未捕获的错误,它只是一个JS对象。对象本身可能具有有关错误的信息,但我们仍然不立即知道它来自何处。在我们处理代码并对其进行调试时,它不是很有用。


throw new Error({'hehe':'haha'}); 

在chrome devtools中看起来像这样:

在此处输入图片说明

展开错误时,使用Error对象引发的错误为我们提供了堆栈跟踪。这为我们提供了有价值的信息,准确地指出了错误的出处,这在调试代码时通常是有价值的信息。还要注意,错误提示为 [object Object],这是因为Error构造函数希望将消息字符串作为第一个参数。当它收到一个对象时,它将把它强制为一个字符串。


2

反应行为

除了其余答案,我想展示一下React的一个区别。

如果抛出,new Error()并且我处于开发模式,则将显示错误屏幕和控制台日志。如果我抛出字符串文字,那么如果我不看控制台日志,我只会在控制台中看到它,并且可能会错过它。

在开发模式下,将错误引发日志登录到控制台显示错误屏幕(该屏幕在生产中将不可见)。

throw new Error("The application could not authenticate.");

反应中的错误画面

而以下代码仅登录到控制台:

throw "The application could not authenticate.";
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.