2011-01-19 50 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語句。