Проверьте, содержит ли переменная числовое значение в Javascript?

В PHP это довольно просто:

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

Но как это сделать в Javascript? Я мог бы использовать регулярное выражение, но есть ли функция для этого?

Ответ 1

Как насчет:

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

Функция isNaN используется для проверки того, является ли значение не числом.

Обновление: Кристоф прав, в JavaScript Булевы типы конвертируются в Number, возвращая значение 1 для true и 0 для false, поэтому, если вы оцениваете 1 + true, результат будет равен 2.

Учитывая это поведение, я обновил функцию, чтобы предотвратить преобразование булевых значений в числовое представление.

Ответ 2

Я не думаю, что какие-то предложения до сих пор на самом деле работают. Например,

!isNaN(parseFloat(foo))

не потому, что parseFloat() игнорирует конечные нечисловые символы.

Чтобы обойти это, вы можете сравнить возвращаемое значение с тем, которое было возвращено с помощью Number() (или, что эквивалентно, с помощью унарного +, но я предпочитаю явное литье):

parseFloat(foo) === Number(foo)

Это будет работать, если обе функции возвращают NaN, потому что NaN !== NaN - true.

Другая возможность заключалась бы в том, чтобы сначала передать в строку, затем на номер, а затем проверить на NaN, то есть

!isNaN(Number(String(foo)))

или эквивалентно, но менее читаемым (но, скорее всего, быстрее)

!isNaN(+('' + foo))

Если вы хотите исключить значения бесконечности, используйте isFinite() вместо !isNaN(), то есть

isFinite(Number(String(foo)))

Явный листинг через Number() на самом деле не нужен, потому что isNan() и isFinite() неточно указывается на число - причина, по которой !isNaN() не работает!

На мой взгляд, наиболее подходящим решением было бы

isFinite(String(foo))

Как отметил Матфея, второй подход не обрабатывает строки, которые содержат только пробелы.

Это не сложно исправить - используйте код из комментария Matthew или

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

Вам нужно будет решить, насколько это лучше, чем сравнение результатов parseFloat() и Number().

Ответ 3

Чтобы проверить типы в 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));
}

Ответ 4

Это проверяет числовые значения, включая номера отрицательных чисел и чисел с плавающей запятой.

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

@Vordreller: Я исправил Regex. Теперь он должен работать правильно.

Ответ 5

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

Это должно сделать трюк.

Ответ 6

Вот что я придумал:

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

Это должно работать с float и ints, положительными и отрицательными. Я не знаю о бесконечности, как обсуждали некоторые из вышеперечисленных ответов.

Если ваше значение действительно может быть числом и не всегда строкой, вы можете изменить === на a ==, и оно будет обрабатывать оба.

Ответ 7

Здесь приведены некоторые тесты для isNaN vs. isFinite и typeof === "number"

http://jsperf.com/isnan-vs-isfinite-vs/3

По-видимому, typeof === "number" примерно в 5 раз быстрее

Ответ 8

Запустите фрагмент кода, чтобы увидеть сравнение лучших ответов по этой теме.

Некоторые тестовые примеры не выделяются (и не вносят вклад в резюме). Эти случаи помечены как неоднозначные, потому что неясно, следует ли считать данное значение или не считаться числом.

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