我知道为什么断言编程是好的,所以我想用JavaScript来使用它。但是,我不想向用户显示错误框,这是不寻常的事情。只是忽略它,让它们重试可能会更好。
例如,此代码将生成错误框并中断用户。
function getDomainFromURL(url) {
assertTrue(url, 'URL should not be null');
...parsing
}
所以,我会这样做。
function getDomainFromURL(url) {
if (!url) return;
...parsing
}
第二个对可用性有好处,我想,第一个对开发有好处。
因此,IMO最好将这些组合起来,使assert
消失在生产代码上。
问题1 你这么认为吗?或者有任何不同的想法?
问题2 如果您这么认为,有没有什么好方法可以使用Spring3框架?
答案 0 :(得分:8)
断言不应用于验证任何类型的用户输入数据。它们也不应用于错误检查。断言是在测试失败的情况下更容易为程序员调试的方法。此外,它还可以让您的代码更易于理解。
考虑这个例子:
function calculateSomeCrazyFormula(a,b,c) {
var d = a+b+c;
....
k = (x + y)*2;
assert(k != 0);
l = d/k;
....
return x;
}
我的公式由它的规范保证 k永远不会为0.这里我在我的代码中使用断言几乎作为注释。它没有验证逻辑 - 它完全相反。使用断言,我验证我的复杂逻辑的实现是否正确。稍后,当我回到我的代码并看到l = d/k
时,我不会怀疑当k为0时会发生什么,因为我在那里看到assert
并明白0
应该永远不会发生。
此外,如果某处出现错误并且0
确实发生了,您通常会看到更深层次的错误。例如:
function otherFormula(a,b,c) {
var x = calculateSomeCrazyFormula(a,b,c);
var y = doSomeStuff(x);
var z = doOtherStuff(y);
return z;
}
如果没有断言,您将得到此函数的错误结果。当你应该是1时,你将不知道为什么你会收到0。你必须逐行开始调试代码并理解出了什么问题。
但是,使用断言,您将立即注意到“断言失败”错误,并立即将查找问题的范围最小化。
断言在任何编程语言(包括Javascript)中都很有用,但它们不应该存在于Live环境中。因此,某些后处理器系统应该在发布之前删除代码中的所有断言。
答案 1 :(得分:4)
我不认为第二个特别好。如果你从一个总是希望返回某个东西的方法中什么都不返回,那么代码可能会在其他地方失败,而不是接近实际问题所在的位置,即在getDomainFromURL
函数内。
如果另一方面,当参数为null时,此方法完全没有返回任何内容,那么添加断言是没有意义的。
就个人而言,我会在开发和生产中随处使用第一种形式。如果断言在生产中失败,那么您将获得有关问题原因的非常有用的反馈(在浏览器,日志等中)。如果你删除断言,你仍然会有一个错误,但是追踪它会更加困难
这种编程风格 - 检查前置条件 - 是所谓的基于合同的编程的一部分。我以前从未听说过“自信编程”一词。
答案 2 :(得分:2)
由于以下几个原因,我认为在Javascript中进行自信编程并不好:
执行此操作的最佳方法是编写单元测试。这样,您可以确保在更新代码时不会破坏代码,这也意味着断言不会出现在您的生产代码中。当然,你可能需要if (condition) error();
之类的东西,因为这些条件可能取决于用户,而不是开发人员。这些将是不可避免的,您需要手动编码。
经验法则:
if (condition) error();
最后,通过单元测试,您可以检查代码是否正确错误。我对JsUnit不太了解,但你可以在测试中做到这样的事情:
assertThrow(somefunc, args, YourError);
在您的代码中使用if (condition) error();
答案 3 :(得分:2)
在处理异步和用户驱动的数据时,总是需要条件错误处理。它发生了。用户和网络搞砸了。这就是人生。你最好的选择是至少有第二个例子 当且仅当有理由期望数据可能已损坏 时。如果您负责提供您正在测试的数据,那么您需要确保 之前 数据有效。
为什么没有组合:
function getDomainFromURL(url) {
if( !assert( url != undefined, 'URL should not be null.' ) )
return '';
// '' is optional, but I don't like returning null if I expect a value.
/* blah blah blah */
}
// as lightweight a function as you can have.
function assert( val, msg )
{
if( !val )
{
console.log( msg );
return false;
}
return true;
}
实际上,想一想,我经常使用那种确切的模式。
答案 4 :(得分:1)
忽略它并让它们重试可能会更好。
无声失败并不是一个好主意。从可用性的角度来看,即使出现错误,用户也应立即对其行为进行反馈。当代码中发生异常时,您应该显示一个简单的错误页面。这里的想法是fail fast。
如果不满足条件,我会让你的断言函数重定向到错误页面,然后记录它。您可以通过设置window.location.href
在Javascript中执行此操作,并通过XHR发布来记录您的错误。
答案 5 :(得分:1)
您可以像这样使用它:
function getDomainFromURL(url) {
assert(url != null, "url is null");
if (!url) return;
...parsing
}
有些人会不同意,但我会尝试找到一种方法来删除生产代码中的断言语句,可能是通过使用预处理器或作为混淆步骤的一部分,如果有的话。这可以提高性能和代码大小,但是您需要确保在assert中调用的代码不会更改程序的状态。这也可能很棘手。我的结论是,在javascript中编写大而强大的程序需要遵守纪律。
作为奖励,请查看可在此处找到的断言: