使用JavaScript进行自信编程

时间:2011-07-14 12:50:33

标签: javascript assert spring-3 assertion

我知道为什么断言编程是好的,所以我想用JavaScript来使用它。但是,我不想向用户显示错误框,这是不寻常的事情。只是忽略它,让它们重试可能会更好。

例如,此代码将生成错误框并中断用户。

function getDomainFromURL(url) {
    assertTrue(url, 'URL should not be null');

    ...parsing
}

所以,我会这样做。

function getDomainFromURL(url) {
    if (!url) return;

    ...parsing
}

第二个对可用性有好处,我想,第一个对开发有好处。 因此,IMO最好将这些组合起来,使assert消失在生产代码上。

问题1 你这么认为吗?或者有任何不同的想法?

问题2 如果您这么认为,有没有什么好方法可以使用Spring3框架?

6 个答案:

答案 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中进行自信编程并不好:

  1. 我不喜欢像这样的错误检查应该在生产环境中完成的事实。
  2. 人们专门为此目的开发了单元测试框架(JsUnit)
  3. 此断言语句会增加代码大小,从而增加下载时间和执行时间。
  4. 执行此操作的最佳方法是编写单元测试。这样,您可以确保在更新代码时不会破坏代码,这也意味着断言不会出现在您的生产代码中。当然,你可能需要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中编写大而强大的程序需要遵守纪律。

作为奖励,请查看可在此处找到的断言:

http://aymanh.com/9-javascript-tips-you-may-not-know/