2013-07-02 49 views
5

我經常做這樣的東西:模式用於治療零truthy

delay = delay || 24; // default delay of 24 hours 

但其實我是想允許0,0 || 24 === 24,而不是0

我想知道最好的模式是從命令行或從哪裏輸入用戶輸入,並且執行相同的邏輯,只將零視爲真理。我想我已經找到了最好的模式是做正是:

delay = (delay === 0 ? delay : (delay || 24)); 

首先,它允許之類的東西'abc',這是真的錯了。但是如果我提前+,它會讓null滑過,這也是錯誤的。其次,非常難看,因爲它顯然是在解決語言缺陷問題,而不是用可用的語言工具做一些優雅的事情。而且不可讀。我正在做一些思路,我想用一行實際的代碼來做(不是技術上的一行,就像這樣)。但大多數其他的想法我已經得到甚至醜陋:

delay = typeof delay === 'number' ? delay : 24; // but typeof NaN === 'number', so 
delay = (!isNaN(delay) && typeof delay === 'number') ? delay : 24; 

注意,這實際上將與字符串工作 - 如果我有興趣在接受"",然後

str = typeof str === 'string' ? str : 'default'; 

由於沒有NaN孔,這是智能可讀的:如果我們有一個字符串使用,否則使用defaut。

還是這條路線:

delay = !isNaN(+delay) ? delay : 24; // fails on null 
delay = !Number.isNaN(+delay) ? delay : 24; // still fails on null 
// same thing with null check, now way uglier than we started 

所以我還是很喜歡我的哈克三元和布爾邏輯更好。是的,我正在尋找一種精簡的單行解決方案,因爲JS充斥着各種模式,而其他許多語言中聰明的東西在JS中被廣泛認可,易讀和清晰。但我是新手,並試圖學習好的模式,因此,這個問題。

更明確的要求:

  • 0需要去0
  • undefined需要去24
  • NaN之外,typeof下的所有實際數字都需要自行解析。
  • 我強烈地感受到null應該去24,因爲我很少使用故意把nullundefined不同的JS代碼。我覺得保持這種方式會更好。
  • 我稍微感覺NaN應該去24,因爲這更接近||模式。麻煩的事情應該默認。
  • 'abc'應該去24 - 在我的真實應用程序這是用戶輸入,並且用戶不應該錯誤地鍵入,說一個電子郵件。
  • '123abc'理想情況下應去24,其轉換爲Number漁獲,但parseInt沒有。我相信電子郵件可以從數字開始,所以這就促使人們認爲這是應該被捕獲的東西。

下劃線或lodash答案是特別接受,,那些你們誰給我講想成爲「聰明」,而不是寫一個2-3線功能。這些庫的存在正是因爲許多簡單的2-3行函數在世界各地許多代碼庫中的許多地方完成了相同的事情,並且它的可讀性和可維護性更強,並且可以將它們隔離爲諸如_.readNumber 。如果不存在這樣的方法,並且我能夠提出足夠一般的要求,我將自己提交一個投票請求,並將其作爲對這個問題的回答發佈。這是我喜歡JS的東西 - 它具有良好的生態系統,因此很有可能而不是必須編寫這些實用程序方法。由於我特別處理用戶輸入,因此編寫稍微更專用的函數並提交給commander.js可能會更好,這是我一直需要的。

+0

爲什麼不'delay = delay> -1:delay:24'?負值是否被接受? –

+0

@ Karl-AndréGagnon在我的案例中沒有,這其實很合理。 – djechlin

+0

「NaN洞」是什麼意思? 'num = typeof num ==='number'如何? num:24'不足? –

回答

1

假設用戶輸入爲一些評論說,那麼它開始爲任何可能的字符串,以便測試它。

delay = /^(\d+)$/.exec(delay) ? Number(RegExp.$1) : 24; 

注意這也防止負整數,雖然沒有作爲一個要求給出是無意義的作爲延遲的時間。

+0

Downvoter會在評論中解釋嗎?該解決方案通過了全部7個給定的要點要求。 – Tim

+0

嗯,我upvoted。當用戶輸入字符串時,正則表達式在這裏可以說是非常正確的。 JS實用程序方法不能像'(\ d +)'那樣把一些合理的東西放在一起。 – djechlin

+0

接受這個答案,因爲它可能是對我的驗證用戶輸入問題的最佳建議。不幸的是,我把這個問題的兩個部分合並在了一起 - 驗證和傳遞價值,而這個問題的後半部分似乎沒有很好的解決方案。 – djechlin

0

如何:

delay = isNaN(parseInt(delay, 10)) ? 24 : delay 

(編輯:我現在看到在這同時,我工作了這一點,在一個控制檯,誠實發生的評論此建議:。d)

如果你絕對需要與領先的數字的字符串是無效的,你將不得不進行類型檢查它:

delay = typeof(delay) === "number" && isNaN(parseInt(delay, 10)) ? 24 : delay 

例如,如果我用你的成語:

delay = (delay === 0 ? delay : (delay || 24)); 

而「延遲」是「123abc」,您的方法將導致延遲仍然是「123abc」,因爲它是一個真值。如果你不打算做明確的類型檢查,你需要使用parseInt來確保你實際上將delay設置爲一個整數類型;如果你不打算做明確的類型檢查,你需要使用parseInt來確保你實際上將delay設置爲整數類型;如果你不打算做顯式類型檢查,即使0是真的,如果delay = delay || 24會將delay設置爲字符串值(如果沒有任何強制或類型檢查的情況下傳遞)。在執行isNaN檢查之前強迫數字確保任何不是有效數字的東西(由parseInt解析;具有前導數字的字符串仍會滑過)確保當您檢查isNaN時,結果將意味着「這是有效的號碼「或」這不是有效的號碼「,而不是」這是NaN「或」這是除NaN以外的任何內容「。

如果您正在進行類型檢查,您並不嚴格需要parseInt,但我認爲從語義角度來看它仍然是一個好主意,因爲它表明您期望並需要一個整數值。

+0

你應該解釋爲什麼'parseInt'應該總是處理用戶輸入的強制性步驟。 – Shmiddty

+0

@Shmiddty應該嗎? ''parseInt('123a')'是'123',這是'Number'會捕獲的錯誤類型 – djechlin

4

無處是int提到的要求,所以假設你要任何號碼,否則默認爲24,你可以這樣做:

delay = isFinite(delay) ? delay : 24; 

或者更安全:

delay = isFinite(parseFloat(delay)) ? delay : 24; 

還是羅伯特檸檬特價:

delay = isFinite(parseFloat(delay))|0||24; 

當然讓人一眼就能理解語句比句法糖更重要。你正在編寫的代碼被人和機器所理解,而不是爲了避開工業間諜。

+0

'isFinite(null)=> true' –

+0

如果delay ==「」? – dandavis

+0

'isFinite(parseFloat(delay));':P – rlemon

4

的乾淨的解決方案,到目前爲止:

delay = numberOrDefault(delay, 24); 

// i = i || 24 doesn't work with i = 0, so this small func takes care of this. 
function numberOrDefault(input, default) { 
    // a few lines handling your case 
} 

不要濫用語言。不要試圖變得聰明。不要試圖混淆你的代碼。它不會爲你的自我服務,並會損害你的代碼的可維護性和可讀性。

功能在那裏,可以有名稱。他們完全是爲了你要找的目的完成的:給一些指令提供名字。使用它們。

+0

我以爲OP想要一個回答? – dandavis

+2

@dandavis你顯然沒有讀到答案。 –

+0

'lookMa && noIfStatement()&& imSoClever()&& i ++' – Esailija

0

不這樣做,即使它可以從字面上你想要什麼:

Number.prototype.valueOf=function(){return this||"0";} 
alert( 0 || 24)// shows: 24 

我認爲這將破壞其他腳本,但是這將是很好,如果我們能夠在做這樣的東西javascript中的塊級別...