В PHP это довольно просто:
is_numeric(23);//true
is_numeric("23");//true
is_numeric(23.5);//true
is_numeric(true);//false
Но как это сделать в Javascript? Я мог бы использовать регулярное выражение, но есть ли функция для этого?
В PHP это довольно просто:
is_numeric(23);//true
is_numeric("23");//true
is_numeric(23.5);//true
is_numeric(true);//false
Но как это сделать в Javascript? Я мог бы использовать регулярное выражение, но есть ли функция для этого?
Как насчет:
function isNumber(n){
return typeof(n) != "boolean" && !isNaN(n);
}
Функция isNaN используется для проверки того, является ли значение не числом.
Обновление: Кристоф прав, в JavaScript Булевы типы конвертируются в Number, возвращая значение 1 для true и 0 для false, поэтому, если вы оцениваете 1 + true
, результат будет равен 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()
.
Чтобы проверить типы в 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));
}
Это проверяет числовые значения, включая номера отрицательных чисел и чисел с плавающей запятой.
function is_numeric(val){
return val && /^-?\d+(\.\d+)?$/.test(val + '');
}
@Vordreller: Я исправил Regex. Теперь он должен работать правильно.
function is_numeric(val) {
return ((+val) == val);
}
Это должно сделать трюк.
Вот что я придумал:
value = "2.34";
if (parseFloat(value).toString() === value) {
alert("number");
}
Это должно работать с float и ints, положительными и отрицательными. Я не знаю о бесконечности, как обсуждали некоторые из вышеперечисленных ответов.
Если ваше значение действительно может быть числом и не всегда строкой, вы можете изменить === на a ==, и оно будет обрабатывать оба.
Здесь приведены некоторые тесты для isNaN vs. isFinite и typeof === "number"
http://jsperf.com/isnan-vs-isfinite-vs/3
По-видимому, typeof === "number" примерно в 5 раз быстрее
Запустите фрагмент кода, чтобы увидеть сравнение лучших ответов по этой теме.
Некоторые тестовые примеры не выделяются (и не вносят вклад в резюме). Эти случаи помечены как неоднозначные, потому что неясно, следует ли считать данное значение или не считаться числом.
// 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>