2009-03-01 112 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>

相关问题