JavaScript错误处理:我能在三元运算符中抛出一个错误吗?

53

我能在三元运算符内部抛出错误吗?下面的写法是有效的吗:

function foo(params) {

    var msg = (params.msg) ? params.msg : (throw "error");

    // do stuff if everything inside `params` is defined
}

我的目标是确保所有需要的参数都在一个param对象中定义,在任何一个参数未定义时抛出错误。

如果这样做是愚蠢的,那么有更好的方法吗?


1
如果你真的想使用条件语句,你可以编写一个函数来代替你抛出错误。var msg = (params.msg) ? params.msg : _throw("error"); function _throw(m) { throw m; } - user1106925
1
想要这样做并不傻,我真的希望我能够实现。仅出于兴趣,C# / .NET 已经支持这个特性有一段时间了。https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.0/throw-expression - Simon_Weaver
这段代码之后会调用什么东西来处理 msg?我理解在 params.msg 没有被赋值时想要抛出一个错误,我也考虑过这样做,但当我意识到这段代码会将 throw message 赋值给 msg 时,在这种情况下,似乎没有必要这样做?至少对于我的使用情况来说是这样的,所以想知道在需要这样做的情况下,msg 是如何被消耗的。 - Kreidol
13个回答

72
你可以这样做:
function foo(params) {

    var msg = (params.msg) ? params.msg : (function(){throw "error"}());

    // do stuff if everything inside `params` is defined
}

虽然它可以实现功能,但我并不推荐这样做,这会使代码难以阅读。

以下代码也可以工作(虽然并没有好多少):

function foo(params) {

    var msg = params.msg || (function(){throw "error"}());

    // do stuff if everything inside `params` is defined
}
或者采用更清晰的方式,创建一个具有名称的函数。
function _throw(m) { throw m; }
function foo(params) {

    var msg = params.msg || _throw("error");

    // do stuff if everything inside `params` is defined
}

1
有趣... +1感谢您提供了不同的方法。我同意这并不是一个好的做事方式。我更喜欢使用多个if语句的方法。 - Hristo
这个回答非常完美,但我并不认为它应该被认可为最佳实践。在我看来,使用“if”条件语句更符合@Dagg Nabbit的暗示思维和整个语言的风格。 - craft

23

不行,绝对不允许。 throw 是一个语句,不能成为表达式的一部分。

不幸的是,我认为这是唯一的方法。您可以在没有括号的情况下使用 if

if(!params.msg) throw new Error("msg is required!");

但是我不知道有任何简单易懂的好方法。


2
嗯...我本来想避免使用if语句,但看起来这样做也能达到同样的效果。感谢你的回答 :) - Hristo

3
这是我用过的更清晰的方法:

这是一个更加简洁的方法,适用于我:

const msg = params.msg ? params.msg : ((function () { throw new Error('Message not found); }()));

2

你可以在三元运算符中像这样抛出错误:

function isPositive(a) {
    if(a > 0)
        return "YES";
    throw a == 0 ? Error("Zero Error") : Error("Negative Error");
}

你确定吗?从三目运算符抛出错误看起来很奇怪,因为三目运算符通常用于设置常量。使用if-else或try-catch会更易读一些,不是吗? - djangofan
理想情况下是这样的,如果有更多的错误需要抛出,那么if else是更好的方法。对于上述情况,我认为三元运算符可以工作,因为没有更多的情况需要覆盖。 - Saurabh
问题在于你必须抛出错误...我猜...所以它并没有完全有条件地执行,因为你没有选择不在这里抛出。 - tikej

1

在@dagg的方法和命名函数示例的基础上进行改进;这里是相同的ES6默认参数:

function _throw(m) { throw new Error(m); }

function foo({ msg = _throw('msg parameter not defined') } = {}) {
  console.log(msg);
}

foo({ msg : 'party people!' }); // :D
foo({}); // throws!


1
这是一个简单的小技巧,可以从三元运算符中抛出异常。我只是在未定义的符号上调用一个不存在、永远不可能存在的属性。我只检查了Chrome,如果需要具有适当的错误消息,则可以捕获并重新抛出,但这是不必要的膨胀。
try {
  var msg = (params.msg) ? params.msg : (void 0).throwError()
}
catch(e) {
  throw new Error('Params has no msg property')
}

0
在使用fetch时遇到了这个问题,这是我针对该特定情况提供的解决方案:
return fetch(url, request)
  .then(response => response.status >= 400 && response.status < 600 
    ? response.json().then(error => {throw new Error(error.message)})
    : response);

请注意 throw 周围的(内联)块,它将箭头函数体从(返回)表达式转换为语句。

0
你可以像这样做:
function foo(params) {

    let msg = params.msg ? params.msg : (() => {throw new Error('Something went wrong')})();

    // do stuff if everything inside `params` is defined
}

0
如果你的目标是nodejs,你可以在表达式中使用这个:
require('assert').fail('Bad response from server or whatever')

给出:

AssertionError [ERR_ASSERTION]: Bad response from server or whatever

0

最简单的方法是使用箭头函数:

err
    ? ()=>{throw err}
    : console.log('smooth')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接