237
var err1 = Error('message');
var err2 = new Error('message');

What's the difference? Looking at them in the chrome console, they look identical. Same properties on the object and the same __proto__ chain. Almost seems like Error acts like a factory.

Which one is correct and why?

Ilia Choly
  • 18,070
  • 14
  • 92
  • 160
  • 5
    All the native constructors are defined in ECMAScript, including their respective behavior when invoked without `new`. – I Hate Lazy Nov 08 '12 at 17:46
  • 6
    See also [When is `new Error()` better than `Error()`?](http://stackoverflow.com/q/38759428/1048572) – Bergi Dec 08 '16 at 05:08

2 Answers2

235

Both are fine; this is explicitly stated in the specification:

... Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
24

Error does act like a factory, like some other native constructors: Array, Object, etc. all check something like if (!(this instanceof Array)) { return new Array(arguments); }. (But note that String(x) and new String(x) are very different, and likewise for Number and Boolean.)

That said, in case of an error, it's not even required to throw an Error object... throw 'Bad things happened'; will work, too
You can even throw an object literal for debugging:

throw {message:"You've been a naughty boy",
       context: this,
       args: arguments,
       more:'More custom info here'};
wchargin
  • 15,589
  • 12
  • 71
  • 110
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • 9
    I'm afraid I don't fully agree. `String("abc")` does not create a `String` object, whereas `new String("abc")` does. – pimvdb Nov 08 '12 at 17:47
  • 2
    @pimvdb: true, I've changed it to `Object` => `Object('foo')` returns a string object... come to thing of it _almost all native constructors_ is a bit wrong... `Number`, `Boolean`,`Date`,`String` all don't...`Array`, `Object` and `Error` do, but `Event` and all `DOMxxxx`-api constructors throw errors – Elias Van Ootegem Nov 08 '12 at 17:49
  • I also think `new Array(arguments)` does not do exactly what `Array(1, 2, 3)` does. But probably I'm just nitpicking :) – pimvdb Nov 08 '12 at 17:57
  • @pimvdb: It probably doesn't, no. Then again: I always advise against the use of `new Array()`, for obvious reasons – Elias Van Ootegem Nov 08 '12 at 20:41
  • 10
    Complementary with regard to throwing strings: [A string is not an error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/) – alex Aug 11 '14 at 07:09
  • 13
    @alex: Granted, throwing non-`Error` instances (or string literals) looses the stack-trace. Just a nit-pick on the linked article: `arguments.callee` is forbidden in strict mode – Elias Van Ootegem Aug 11 '14 at 07:25
  • _“You can even throw an object literal for debugging”_ — or simply use `debugger;` or [`console.trace`](https://developer.mozilla.org/en-US/docs/Web/API/Console/trace). – Sebastian Simon Jan 16 '21 at 08:41