Ответов (9)9
Что о:
function isNumber(n){
return typeof(n) != "boolean" && !isNaN(n);
}
IsNaN встроенной функции используется для проверки , является ли значение не является числом.
Обновление: Кристоф прав, в JavaScript логические типы конвертируются в Number, возвращая 1 для истины и 0 для false, поэтому, если вы оцениваете, 1 + true
результат будет 2.
Учитывая такое поведение, я обновил функцию, чтобы предотвратить преобразование логических значений в их числовое представление.
Вот что я придумал:
value = "2.34";
if (parseFloat(value).toString() === value) {
alert("number");
}
Это должно работать с числами с плавающей запятой и целыми числами, положительными и отрицательными. Я не знаю о бесконечности, как уже говорилось в некоторых ответах выше.
Если ваше значение может быть числом, а не всегда строкой, вы можете изменить === на ==, и он будет обрабатывать и то, и другое.
Вот несколько тестов для isNaN vs. isFinite и typeof === "number"
http://jsperf.com/isnan-vs-isfinite-vs/3
Видимо typeof === "number" примерно в 5 раз быстрее
Вот мое решение: ES6 / 2015
Отказ от ответственности : это решение работает только в том случае, если пользователь отправляет тип числа в качестве ввода. Например: 23 - это числовой тип, но «23» - это не числовой тип, это строковый тип.
function isValidNumber(value) {
return typeof value === 'number' && Number.isNaN(value) === false;
}
Тестовые кейсы
isValidNumber(10) // true
isValidNumber(10.34) // true
isValidNumber('geo10') // false
isValidNumber('10geo') // false
isValidNumber('') // false
isValidNumber(NaN) // false
isValidNumber(true) // false
isValidNumber(false) // false
Запустите фрагмент кода, чтобы увидеть сравнение наиболее популярных ответов по этой теме.
Некоторые тестовые примеры не выделяются (и не вносят вклад в сводку). Эти случаи помечены как неоднозначные, потому что неясно, следует ли считать данное значение числом.
// 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>
Для проверки типов в 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));
}
Я не думаю, что до сих пор ни одно из предложений действительно работает. Например
!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))
Как отметил Мэтью, второй подход не обрабатывает строки, которые содержат только пробелы.
Исправить несложно - используйте код из комментария Мэтью или
isFinite(String(foo).trim() || NaN)
Вам нужно будет решить, лучше ли это, чем сравнивать результаты parseFloat()
и Number()
.