Ошибка throw ('msg') против новой ошибки throw ('msg')

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

Какая разница? Глядя на них в хромированной консоли, они выглядят одинаково. Одинаковые свойства объекта и одинаковые __proto__цепочки. Похоже, Errorдействует как фабрика.

Какой из них правильный и почему?

Илья Чоли
источник
5
Все собственные конструкторы определены в ECMAScript, включая их соответствующее поведение при вызове без new.
Я ненавижу Ленивого
4
Смотрите также Когда new Error()лучше чем Error()?
Берги

Ответы:

166

Оба в порядке; это явно указано в спецификации :

... Таким образом, вызов функции Error(…)эквивалентен выражению создания объекта new Error(…)с теми же аргументами.

pimvdb
источник
7
Это правда и в ES6?
17
4
Да. Текущие документы см .: ecma-international.org/ecma-262/6.0/…
TheStherSide
@paulmelnikow - Да. Обратная совместимость является высшим приоритетом TC39. Мантра «не ломай паутину».
TJ Crowder
17

Errorэто действует как фабрика, как и некоторые другие родные конструкторов: Array, Objectи т.д. все проверки что - то подобное if (!(this instanceof Array)) { return new Array(arguments); }. (Но учтите, что String(x)и new String(x)очень разные, и аналогично для Numberи Boolean.)

Тем не менее, в случае ошибки даже не требуется бросать Errorобъект ... throw 'Bad things happened';тоже будет работать.
Вы даже можете бросить литерал объекта для отладки:

throw {message:"You've been a naughty boy",
       context: this,
       args: arguments,
       more:'More custom info here'};
Элиас Ван Отегем
источник
9
Боюсь, я не совсем согласен. String("abc")не создает Stringобъект, тогда как new String("abc")делает.
pimvdb
2
@pimvdb: правда, я изменил его к Object=> Object('foo')возвращает объект строки ... пришел вещь этого почти все нативные конструкторов это немного неправильно ... Number, Boolean, Date, Stringвсе не ... Array, Objectи Errorделать, но Eventи все DOMxxxxконструкторы -api выдают ошибки
Элиас Ван Отегем
Я также думаю, new Array(arguments)что не делает именно то, что Array(1, 2, 3)делает. Но, вероятно, я просто придираюсь :)
pimvdb
8
Дополнительно к метанию строк: строка не является ошибкой
alex
11
@alex: допустим, выбрасывая неэкземпляры Error(или строковые литералы) теряет трассировку стека. Просто ничтожество на связанной статье: arguments.calleeзапрещено в строгом режиме
Элиас Ван Отегем