【问题标题】:Making Params Required in Function使函数中需要的参数
【发布时间】:2016-04-12 17:24:57
【问题描述】:

如果一个函数被调用并且缺少正确执行被调用函数所必需的参数,那么抛出错误是一种好习惯吗?

例如(在 JavaScript 中):

var sayHi = function(name) {
  console.log(name + ' says hi!');
}

对比

var sayHi = function(name) {
  if(!name) { throw new Error('param is missing'); }
  console.log(name + ' says hi!');
}  

对于第二个示例是否是一种良好的编码实践,或者它是否只会增加不必要的膨胀,可能导致在跨越数十甚至数百个文件的更复杂的程序中经常引发不必要的错误,是否有强烈的意见?

【问题讨论】:

  • 这完全取决于意见。我倾向于不包括这样的检查,因为它们会减慢我的代码,让程序员有责任正确调用他们的函数。或者,您可以使用静态类型语言,例如 TypeScript,它确保始终使用正确数量的参数调用函数。
  • @raiti13 如果某些答案对您有所帮助,请接受它以便为未来的用户提供帮助:)

标签: javascript performance function error-handling parameter-passing


【解决方案1】:

第一件事:

由您决定是否应该或不应该throw 异常而不是return 错误代码(或null,或其他)。

据我所知,只要您正确处理它们,抛出异常而不是返回错误并没有什么大问题。

这就引出了以下问题:

什么时候正确抛出异常(或JS中的错误)?

这个问题很棘手,这里应该标记并关闭为“主要基于意见”,因为这取决于个人意见......好吧,也许......

一个类似的问题(嗯..这个确切的问题)已经被问到并回复了here,我发现自己同意接受的答案,总结在这个评论中:

没错!当且仅当函数前提条件(关于参数的假设)被破坏时,才会引发异常! – @Lightman

在您的情况下,如果您的函数(您的预期参数)的假设被违反:是,抛出异常,因为 JS 没有提供任何语法构造来将函数参数设置为 required


使用 ES6,您可以使用 default parameters 来强制执行您想要的行为:
function required() {
  throw new Error('Missing parameter');
}

function foo(aRequiredParameter = required()) {

  // Use your required parameter
  console.log("Hello " + aRequiredParameter);
}

// Hence:
foo("World") // OK
foo()        // -> Throws exception

示例取自here,而here 您可以找到有关此功能的更多示例。

这是可以实现的,因为当aRequiredParameter 没有被传递时,它的默认值将被分配(在这种情况下被调用),因此将抛出异常/错误。

【讨论】:

    【解决方案2】:

    你可以通过 es6 传递一个立即抛出错误作为默认值的函数来实现这一点

    const err = msg => { throw Error( msg ) }
    
    const sayHi = function(name = err('Name is undefined')) {
      console.log(name + ' says hi!');
    }
    

    这比在函数体内包含if 语句的性能稍好,并提高了可读性。您可以做的另一个想法是构建一个可以做同样事情的装饰器。比如:

    @required( 'name')
    const sayHi = function(name = err('Name is undefined')) {
      console.log(name + ' says hi!');
    }
    

    正如您在问题Is there a strong opinion 中提到的那样,答案只能是固执己见,因此我认为您应该始终制定错误处理策略。无论是在功能层面还是在应用层面。在我看来,错误处理不太可能成为您的性能瓶颈。

    【讨论】:

    • 这不能回答问题。这只是一种方便的方式来做 OP 已经在做的事情。他们在问他们是否应该在没有给出参数时抛出错误。
    • @MikeC 将其作为默认参数,而不是在函数体内部进行检查,从而提高了性能并使代码更具可读性......所以我认为与问题无关。无论如何,谢谢你的反对。
    • 除非它没有。该检查仍在某处执行,如果您是 compiling your code down to ES5,则它会直接转换为类似于 OP 发布的检查。
    • 当前的 ES6 实现,尤其是默认参数,效率不高。向我证明这在当前的 ES6 环境中更快。此外,这再次没有解决实际问题,即“这种情况下的最佳实践是什么?”
    • @MikeC 好吧,是的,我同意,如果您将代码转换为 ES5,当然没有区别。但是如果你不检查它的原生检查 vs js 检查。
    【解决方案3】:

    这取决于。您几乎总是应该有某种错误处理,但哪种处理取决于具体情况。

    有时只是抛出一个错误就可以了,其他时候你可能想在遇到错误时做点什么。

    您可以使用 try/catch 之类的东西,或者,在这种情况下,只需检查 undefined 并对其进行处理。

    【讨论】:

      猜你喜欢
      • 2013-09-30
      • 2012-11-10
      • 2021-01-31
      • 2015-03-23
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      相关资源
      最近更新 更多