2009-03-01 109 views
11

在PHP中,這是很容易:檢查一個變量是否包含Javascript中的數值?

is_numeric(23);//true 
is_numeric("23");//true 
is_numeric(23.5);//true 
is_numeric(true);//false 

但是我怎麼做到這一點的Javascript? 我可以使用一個正則表達式,但是有這個功能嗎?

+0

可能重複的[在JavaScript驗證號碼 - 則IsNumeric()](http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric) – acdcjunior 2014-02-27 16:24:14

回答

23

什麼:

function isNumber(n){ 
    return typeof(n) != "boolean" && !isNaN(n); 
} 

isNaN內置函數是用來檢查一個值是否一個數字。

更新:克里斯托夫是正確的,在JavaScript中布爾類型轉換爲數字,返回1真,0假的,所以如果你評估1 + true結果將是2

考慮到這種行爲我已更新函數以防止將布爾值轉換爲其數字表示形式。

1
function is_numeric(val) { 
    return ((+val) == val); 
} 

這應該可以做到。

+0

的反例如。 +假== FALSE;正無窮==無限; +''==''... – bobince 2009-03-02 00:02:45

+0

哎呀,忘了關於錯誤。至於無窮大,我確實認爲這會被認爲是一個數字...... +「==」返回0,所以按預期工作。我猜只有真和假是特例,取決於你是否計算無窮大。 – Aistina 2009-03-02 00:20:48

3

這將檢查數值,包括負值和浮點數。

function is_numeric(val){ 
    return val && /^-?\d+(\.\d+)?$/.test(val + ''); 
} 

@Vordreller:我糾正了正則表達式。它應該現在正常工作。

+0

我認爲這可能只是正確的一個:) – AntonioCS 2009-03-02 10:49:25

+0

這是簡單和正確的檢查數字 – praveenjayapal 2009-03-02 12:58:26

+0

試試這個: document.write(is_numeric(「23a5」)); 它會寫「true」 – Vordreller 2009-03-03 20:48:54

5

要檢查在JavaScript中,你可以使用typeof操作類型:

js> var x = 1; 
js> typeof(x); 
number 

所以:如果你想強迫一個變量到整型值

if (typeof(x) === 'number') { 
    // Do something 
} 

,您可以使用parseInt(x, 10)它將以10爲底的整數解析該值。同樣,如果需要浮點值,則可以使用parseFloat。然而,這些將永遠強制無論如何傳遞null,true等將始終返回一個數字。但是,您可以通過致電isNaN來檢查其是否有效。

所以,把他們放在一起:

!isNaN(parseFloat(23)) // true 
!isNaN(parseFloat('23')) // true 
!isNaN(parseFloat(23.5)) // true 
!isNaN(parseFloat(true)) // false 

function isNumber(x) { 
    return !isNaN(parseFloat(x)); 
} 
14

我不認爲任何的建議,到現在實際工作。例如

!isNaN(parseFloat(foo)) 

不會因爲parseFloat()忽略尾隨的非數字字符。

要解決這個問題,你可以在返回值(通過使用一元+或等價的,但我更喜歡明確的鑄造)比較通過​​由鑄造返回的一個:

parseFloat(foo) === Number(foo) 

這仍然可以工作如果兩個函數返回NaN,因爲NaN !== NaNtrue

另一種可能性是首先鑄造到串,然後,以號碼,然後檢查NaN,即

!isNaN(Number(String(foo))) 

或等價地,但不太可讀的(但最有可能更快)

!isNaN(+('' + foo)) 

如果要排除無窮大值,請使用isFinite()而不是!isNaN(),即

isFinite(Number(String(foo))) 

通過​​顯式投射實際上是不必要的,因爲isNan()isFinite()會隱式轉換爲數字 - 這就是爲什麼!isNaN()不起作用的原因!

在我看來,最合適的解決方案,因此將

isFinite(String(foo)) 

馬修指出,第二種方法不處理字符串僅包含空格正確。

不難解決 - 從馬修的評論或

isFinite(String(foo).trim() || NaN) 

使用代碼,就必須決定,如果這仍然比比較parseFloat()和​​結果更好。

0

這就是我想出了:

value = "2.34"; 
if (parseFloat(value).toString() === value) { 
    alert("number"); 
} 

這應該與花車和整數,正面和負面的工作。我不知道無窮大,因爲上面的一些答案已經討論過了。

如果您的值可能實際上是一個數字而不總是一個字符串,您可以將===更改爲一個==,它將處理這兩個。

0

運行的代碼片段查看關於此主題的最佳答案的比較。

某些測試案例沒有突出顯示(並且沒有對摘要做出貢獻)。這些情況被標記爲不明確,因爲不清楚給定的值是否應該被視爲數字。

// Each of these functions should output a truthy/falsy value if the input is 
 
// a number 
 
const solutionsToTest = [ 
 
    v => parseFloat(v), 
 
    v => Number(v), 
 
    v => !isNaN(v), 
 
    v => typeof v != "boolean" && !isNaN(v), 
 
    v => isFinite(String(v)), 
 
    v => !isNaN(parseFloat(v)) && isFinite(v) 
 
]; 
 

 
const testCases = [ 
 
    //[ Test Name, Test Value, Expected Output, Is Ambiguous ] 
 

 
    // Whitespace 
 
    ['""', "", false, false], 
 
    ['"\\t"', "\t", false, false], 
 
    ['" "', " ", false, false], 
 

 
    // Infinity 
 
    ['"Infinity"', "Infinity", false, true], 
 
    ['"+Infinity"', "Infinity", false, true], 
 
    ["-Infinity", -Infinity, false, true], 
 
    ["Infinity", Infinity, false, true], 
 

 
    // Numbers mixed with symbols 
 
    ['"123abc"', "123abc", false, true], 
 
    ['"abc123"', "abc123", false, false], 
 
    ['".0."', ".0.", false, false], 
 
    ['"1."', "1.", true, true], 
 
    ['"."', ".", false, true], 
 
    ['"01"', "01", true, true], 
 
    ['"-0"', "-0", true, true], 
 
    ["+1", +1, true, true], 
 
    ["-1", -1, true, true], 
 

 
    // Other js types 
 
    ["'null'", "null", false, false], 
 
    ["'true'", "true", false, false], 
 
    ["'false'", "false", false, false], 
 
    ["null", null, false, false], 
 
    ["true", true, false, false], 
 
    ["false", false, false, false], 
 
    ["NaN", NaN, false, false], 
 
    ["[]", [], false, false], 
 
    ["{}", {}, false, false], 
 
    ["/./", /./, false, false], 
 
    ["() => {}",() => {}, false, false] 
 
]; 
 

 
const styles = { 
 
    code: { 
 
    fontFamily: "monospace", 
 
    fontSize: 16 
 
    }, 
 
    success: { 
 
    backgroundColor: "#00ff5478" 
 
    }, 
 
    failure: { 
 
    backgroundColor: "#ff00008c" 
 
    } 
 
}; 
 

 
class TestCaseTable extends React.Component { 
 
    static renderTableHeader(solutionsToTest) { 
 
    return (
 
     <tr> 
 
     <th> 
 
      <p>Test Case</p> 
 
     </th> 
 
     {solutionsToTest.map(f => (
 
      <th key={f.toString()}> 
 
      <p style={styles.code}>{f.toString()}</p> 
 
      </th> 
 
     ))} 
 
     </tr> 
 
    ); 
 
    } 
 
    static renderTableRow(testCase, solutionsToTest) { 
 
    const [testName, input, expectedOutput, isAmbiguous] = testCase; 
 
    return (
 
     <tr key={testName}> 
 
     <td style={styles.code}>{testName}</td> 
 
     {solutionsToTest.map(f => { 
 
      const output = Boolean(f(input)); 
 
      const style = isAmbiguous 
 
      ? {} 
 
      : output == expectedOutput ? styles.success : styles.failure; 
 
      return (
 
      <td style={style} key={f.toString()}> 
 
       <p>{output + ""}</p> 
 
      </td> 
 
     ); 
 
     })} 
 
     </tr> 
 
    ); 
 
    } 
 
    render() { 
 
    // Sort test cases, put the ambiguous ones after (but maintain stable sort 
 
    // order) 
 
    let sortedCases = [ 
 
     ...testCases.filter(([a, b, c, ambiguous]) => !ambiguous), 
 
     ...testCases.filter(([a, b, c, ambiguous]) => ambiguous) 
 
    ]; 
 
    return (
 
     <table> 
 
     <thead>{TestCaseTable.renderTableHeader(solutionsToTest)}</thead> 
 
     <tbody> 
 
      {sortedCases.map(tc => 
 
      TestCaseTable.renderTableRow(tc, solutionsToTest) 
 
     )} 
 
     </tbody> 
 
     </table> 
 
    ); 
 
    } 
 
} 
 
class TestCaseSummaryTable extends React.Component { 
 
    renderTableHeader(solutionsToTest) { 
 
    return (
 
     <tr> 
 
     <th>Summary</th> 
 
     {solutionsToTest.map(f => (
 
      <th key={f.toString()}> 
 
      <p style={styles.code}>{f.toString()}</p> 
 
      </th> 
 
     ))} 
 
     </tr> 
 
    ); 
 
    } 
 
    renderSuccessRateRow(solutionsToTest, testCases) { 
 
    // Ignore potentially ambiguous test cases 
 
    testCases = testCases.filter(
 
     ([name, input, expected, ambiguous]) => !ambiguous 
 
    ); 
 

 
    const numSuccess = testSolution => 
 
     testCases.reduce((succeeded, [name, input, expected]) => { 
 
     return succeeded + (Boolean(testSolution(input)) == expected ? 1 : 0); 
 
     }, 0); 
 

 
    return (
 
     <tr> 
 
     <td> 
 
      <p>Test Success</p> 
 
     </td> 
 
     {solutionsToTest.map(f => (
 
      <td> 
 
      <p> 
 
       {numSuccess(f)}/{testCases.length} 
 
      </p> 
 
      </td> 
 
     ))} 
 
     </tr> 
 
    ); 
 
    } 
 
    render() { 
 
    return (
 
     <table> 
 
     <thead>{this.renderTableHeader(solutionsToTest)}</thead> 
 
     <tbody>{this.renderSuccessRateRow(solutionsToTest, testCases)}</tbody> 
 
     </table> 
 
    ); 
 
    } 
 
} 
 

 
const root =() => { 
 
    return (
 
    <div> 
 
     <TestCaseSummaryTable /> 
 
     <TestCaseTable /> 
 
    </div> 
 
); 
 
}; 
 

 
ReactDOM.render(root(), document.querySelector("#application"));
td { 
 
    text-align: center; 
 
    vertical-align: middle; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="application"></div>

相關問題