2011-01-19 42 views
13

显式检查布尔值是否被认为是错误的。做一个简单的if(success)会更好吗?正在通过设计检查真正的错误吗?

我见过关于if (someBoolean === true)是如何在强类型语言中使用可怕代码的各种笑话,但它在弱类型语言中也被认为是不好的?

这将适用于任何弱类型语言,做强制类型转换上的if语句。

一个具体的例子是:

var onSuccess = function (JSONfromServer) { 
    // explicitly check for the boolean value `true` 
    if (JSONfromServer === true) { 
     // do some things 
    } 
} 

// pass it to an ajax as a callback 
doSomeAjax(onSuccess); 

[编辑]

在这种特定情况下成功变量是任何有效的JSON从服务器返回。所以它可能是任何东西。如果它的布尔值为true,那么发生成功。如果它是一些错误处理对象,那么它将被处理。如果是别的东西,那么它可能会被安静地处理。

此问题已越来越服务器返回true作为JSON和检查处理,其中操作成功的情况下的好办法。

我想避免特定于JavaScript的& AJAX虽然。

回答

8

我对此有两个想法。

在一个方面,你已经发布的代码样本是不错的,因为使用Javascript处理强制类型转换的方式。只要successtruthy - 例如,一个简单的if (success)将进入if区块。一个非空字符串将会这样做。三重等于保证success确实是布尔值true,这是一个比你使用较短版本(可能是你想要的)更强大的保证。

不过,如果你需要 - 即你不知道success是否会是一个布尔值,或串,或整数 - 我会说这是本身就是一个代码味道。无论你如何进行比较,我总是会比较一个变量,这个变量将不可避免地是一个布尔值;在这一点上,使用哪种形式的比较并不重要,因为它们是相同的。事实上,我甚至引入了“冗余”的变量,像这样:

var successCount = items.size(); // or some other way to get an integer 
var success = successCount > 0; 
if (success) { 
    ... 
} 

所以,嗯,是的。我认为任何人都不会因为功能上的差异而抱怨===的(明确)使用。但同样的道理,如果你明确使用布尔值success的标志,那么我认为别人也不应该抱怨短风格。 (关于你的第一句话,我认为在动态类型语言中显式检查布尔值true是不好的,如果这个值实际上是你想要的。当静态类型已经约束了它时,这只是多余的。变量是一个布尔值)。

+0

在这种特殊情况下,ajax调用将返回一些JSON数据,这些数据可能是布尔“真”或某种错误处理对象。我想最好是检查错误对象并处理它,并让`true`事件成为else块。 – Raynos 2011-01-19 12:15:31

+0

+1表示可以返回true或*真值的函数是代码异味。 – 2011-01-19 12:16:19

2

什么可以出错?确切地说,没有。在最好的情况下,你的函数什么都不做。如果有一些随机论点被接受为true,那更好。

如果使用true所有其他的时间,则还需要检查明确它。

虽然我确定支持Python中的if foo:,但这里有一个很大的区别,那就是最终一些随机jQuery程序员可能会变得很长,并认为“哦!它也适用于字符串和new Boolean()“并使用它。

关于肖恩建议使用!!这实际上取决于你是否只想要一个布尔值被接受或者是否是真的。对于一个干净的API,我只会接受布尔值。

13

用JavaScript它的价值明知超越布尔真假,值可以是truthyfalsy

考虑:

if (false)  // evaluates to false. 
if (0)   // evaluates to false, 0 is falsy. 
if ("")  // evaluates to false, empty strings are falsy. 
if (null)  // evaluates to false, null values are falsy. 
if (undefined) // evaluates to false, undefined values are falsy. 
if (NaN)  // evaluates to false, NaN is falsy. 

为对象的所有其他值truthy。

如果真值和虚假值导致逻辑中的错误,则应考虑明确使用===!==运算符来确保对象按类型和值进行比较。

1

我读过很多关于JavaScript的文章,我从来没有见过任何人说if(success)是一个不好的习惯。我会做。你确定success参数总是布尔值吗?现在,如果这会变成别的东西,你必须编辑这个函数。但是,如果您只是使用if(success),它将适用于其他“truthy”和“falsey”值,如字符串vs空字符串,或1 vs 0.

如果要将任何参数转换为布尔值,你可以双重否定它:​​;但是在这样的条件下这不是必需的。

5

一般来说,你还指望布尔变量的名称,如:

success, enabled, pass 

有一个真正的价值。所以

if(success) //or 

if(enabled) //or 

if(pass) //or 

if(enabled) //or 

是可以理解和逻辑上可读的。但如果你有变量,如:

result, status, port1.bit7 

,最好是写:

if(result == true) //or 

if(status == false) //or 

if(port1.bit7 == true) 

,因为它以这种方式比下面的例子很容易理解:

if(result) 
{ 
    .... 
} 

可读性是可维护性。

0

它是代码味道或气味语言或实现的细节或公约的问题?

真的,这取决于情况。

把所有假值和所有真值成桶简化的东西,直到分歧的问题,无论是糟糕的代码设计,或者是因为它确实不管出于某种原因。

Hoare对发明null参考文件表示道歉,这与我所看到的这个真相问题的根源很接近。 JavaScript的设计只是通过增加更多的真值来混淆这个问题,导致许多人只是主张明确检查以避免难以追查错误(道格拉斯克罗克福德)。 JavaScript社区已经接受了这种语言本身,有点卡住了。 Python核心团队提倡相反,因为语言设计似乎是在简化事物而不是混淆事物,而核心团队仍在计划改变语言。小的迭代变化是随着时间的推移而发生巨大改进的本质,无论是约定还是语言设计。

两者都是他们特殊情况的好策略。我并不是说这是改进的唯一来源,但这是目前改进的主要来源。

例如,TrueFalse实际上是Python中的int的子类,具体为0和1。这有几个设计好处。然后PEP8主张喜欢指定可选参数时做

if a_reference: 
    pass 

唯一一次None真的连需要在Python中使用的。

def foo(bar=optional): # NOTE I made up this idealistic construct 
    """Looks good at the surface""" 
    pass 

def foo(bar=None): 
    """But this is clear to the programmer""" 
    pass 

的JavaScript隐含了所有变量作为可选:

function foo(x, y, z) { 
    // Certainly not clear to the programmer. 
} 

而且克罗克福德主张明确检查的事情,试图增加一些清晰的语言。

if (foo === undefined) { 
    // pass 
} 

基本上JavaScript的加入空引用#2,被称为undefined。我还认为编程社区认为JavaScript语言如此糟糕,他们认为增加使用诸如CoffeeScript,GWT,睡衣之类的东西的复杂性,以获得更好的客户端语言是公平的权衡。当然,我并不同意增加的复杂性,但遗憾的是,有些人可能至少暂时受益,并且能够更快地完成工作,而不是处理JavaScript。尽管如此,我认为这是一个愚蠢的决定。

sessionStorage.setItem('completed',true); 

它实际上将被转换为字符串和“真”存储:

1

为了增加这次谈话,sessionStorage的和localStorage的变量只能所以今天如果你使用存储为字符串。 我见过很多人的写作方法和转换操​​作此值,使他们能够使用一个布尔值,其中一个简单的

if sessionStorage.getItem('completed') === 'true'; 

就足够了,并且在我看来完美清晰性和可维护性使用if语句。