使用断言在node.js中进行防御性编程

Moi*_*aja 15 javascript coding-style node.js

考虑到有时节点中的错误消息特别无用,我喜欢在我的函数中自由地使用断言,以便尽快捕获编程错误,并且我可以得到一条消息,通常可以查明问题.

function doSomething(arg1, arg2){
  assert(!arg1, "arg1 is undefined");
  assert(!arg2, "arg2 is undefined");
  assert(!arg1.expectedFn, "arg1 does not have expectedFn");

  arg1.expectedFn(function(blah){
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

在节点/ javascript程序中这是一件特别糟糕的事吗?这会对性能产生影响吗?

Bub*_*les 6

(这更像是一个意见而非事实的帖子,所以把它当作它的价值)

断言绝对没有对性能有任何好处,但是在适度使用中我怀疑它们对物质的影响非常严重.也就是说,一般来说,良好的测试覆盖率优于尽可能断言.另外,你写的断言应该不是多余的,因为在运行时自然会抛出什么错误,除非它们特别不透明.

让我们考虑一下doSomething的修改版(并且有点人为) -

function doSomething(arg1, arg2){
  var res = arg1.expectedFn(function(blah){
    ...
  }
  return res + arg2;
}
Run Code Online (Sandbox Code Playgroud)

我认为检查arg1是否存在没有意义,或者它包含一个函数名称expectedFn.如果其中任何一个未定义,javascript运行时将抛出一个相当容易理解的TypeError,它将准确地说出发生了什么; 断言是多余的.

但是,您可能会发现在这里测试arg2是可取的.假设它是未定义的,res是一个字符串或数字 - 然后你最后会在字符串后附加"undefined",或者返回NaN.两者都是相当微妙的错误,可以长时间存在而没有人注意到 - 如果你希望它尽快失败而不是为了调试目的,那么你可能想要添加一些断言以确保它是正确的类型.

一般来说,如果你担心严谨,我相信在编写综合测试时会更好地使用能量:编写完全覆盖doSomething被调用的情况的测试可能会导致比断言更好,更强大的开发过程.在一些情况下,断言是合适的,但它们仅限于畸形结果可以存在很长时间而没有任何直接错误但仍然能够导致不良副作用的情况.

  • 肯定没有替代测试.但是我的观点是,当你创建一个API时,错误是API本身的一部分所以说"你传递了一个无效的参数"会比"expectedFn在undefined上不存在"更可取吗?你同意吗? (5认同)