2009-03-01 10 views
11

En PHP, que es bastante fácil:¿Verifica si una variable contiene un valor numérico en Javascript?

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

Pero, ¿cómo puedo hacer esto en Javascript? Podría usar una expresión regular, pero ¿hay alguna función para esto?

+0

posibles duplicados de [Validar números en JavaScript - IsNumeric()] (http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric) – acdcjunior

Respuesta

23

¿Qué hay de:

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

La función incorporada isNaN se utiliza para comprobar si un valor es no un número.

Actualización: Christoph tiene razón, en los tipos de JavaScript booleanas son convertibles en número, devolviendo el 1 de verdadero y falso a 0, por lo que si se evalúa 1 + true el resultado será 2.

Teniendo en cuenta que este comportamiento He actualizado la función para evitar la conversión de valores booleanos a su representación numérica.

+0

-1: no funciona, por ejemplo '! IsNaN (true)' es 'true' porque' isNaN (foo) 'es equivalente a' isNaN (Number (foo)) ' – Christoph

+1

- 1: ¡Esto no funciona! Pasar una cadena vacía o nulo devuelve verdadero en IE7! Debe ser: return n! = Null && n! = "" && typeof (n)! = "Boolean" &&! IsNaN (n); –

+1

¡Incluso el carácter de espacio vuelve verdadero, por lo que hay más trabajo por hacer! –

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

Eso debería hacer el truco.

+0

contraejemplos p.ej. + falso == falso; + Infinito == Infinito; + '' == '' ... – bobince

+0

Vaya, se olvidó de lo falso. En cuanto al infinito, creo que se consideraría un número ... + "==" devuelve 0, por lo que funciona como se esperaba. Supongo que solo verdaderos y falsos son casos especiales, dependiendo de si cuentas Infinity o no. – Aistina

3

Esto comprueba los valores numéricos, incluidos los números negativos y de coma flotante.

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

@Vordreller: corregí la expresión regular. Debería funcionar correctamente ahora.

+0

Creo que este podría ser el correcto :) – AntonioCS

+0

Esto es simple y correcto para comprobar el – praveenjayapal

+0

numérico intente esto: document.write (is_numeric ("23a5")); Escribirá "verdadero" – Vordreller

5

Para comprobar tipos en javascript que puede utilizar el typeof operador:

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

Así:

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

Si quiere coaccionar el valor de una variable en un número entero, se puede utilizar parseInt(x, 10) que analizará el valor como un entero en la base 10. De manera similar, puede usar parseFloat si quiere un valor de coma flotante. Sin embargo, estos forzarán siempre independientemente del tipo, por lo que si pasa null, true, etc., siempre devolverá un número. Sin embargo, puede verificar si es un número válido llamando al isNaN.

lo tanto, poner todo junto:

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

o

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

no funciona: 'parseFloat()' ignora los caracteres no numéricos finales – Christoph

14

no creo que ninguna de las sugerencias hasta ahora trabajar realmente. Por ejemplo

!isNaN(parseFloat(foo)) 

no lo hace porque parseFloat() ignora arrastrar caracteres no numéricos.

Para evitar esto, se podía comparar el valor devuelto a la devuelta por un elenco través Number() (o equivalentemente usando unario +, pero yo prefiero conversión explícita):

parseFloat(foo) === Number(foo) 

Esto seguirá funcionando si ambas funciones devuelven NaN porque NaN !== NaN es true.

Otra posibilidad sería la primera colada de cadena, entonces al número y luego comprobar si hay NaN, es decir

!isNaN(Number(String(foo))) 

o de manera equivalente, pero menos legible (pero muy probablemente más rápido)

!isNaN(+('' + foo)) 

Si desea excluir valores infinitos, use isFinite() en lugar de !isNaN(), es decir,

isFinite(Number(String(foo))) 

El lanzamiento explícito a través de Number() es realmente innecesario, porque isNan() y isFinite() se convierten en números implícitamente - ¡esa es la razón por la cual !isNaN() no funciona!

En mi opinión, la solución más adecuada, por lo tanto sería

isFinite(String(foo)) 

Como Mateo señaló, el segundo enfoque no controla cadenas que sólo contienen espacios en blanco correctamente.

No es difícil de solucionar - utilizar el código de comentario de Mateo o

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

Usted tendrá que decidir si eso es aún mejor que la comparación de los resultados de parseFloat() y Number().

+1

Esto da falsos positivos para 'isFinite (String (" "))' y 'isFinite (String (" "))'. Tal vez use 'String (foo) .trim()! ==" "&& isFinite (String (foo))'? –

+0

@MatthewStrawbridge: tenga en cuenta que 'parseFloat (...) === Number (...)' maneja correctamente este caso; Veré si puedo guardar el segundo enfoque – Christoph

+0

@MatthewStrawbridge: [x] hecho – Christoph

0

Esto es lo que ocurrió:

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

Esto debería funcionar con flotadores y enteros, positivos y negativos. No sé sobre el infinito, como algunas de las respuestas anteriores han discutido.

Si su valor puede ser realmente un número y no siempre una cadena, puede cambiar el === a a == y manejará ambos.

0

Ejecutar el fragmento de código para ver comparaciones de las principales respuestas sobre este tema.

Algunos casos de prueba no están resaltados (y no contribuyen al resumen). Estos casos se marcan como ambiguos porque no está claro si un valor determinado debe o no considerarse un número.

// 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>

Cuestiones relacionadas