Как опознать число?
В продолжение темы «Как опознать RegExp»
Известно, что в JavaScript NaN (Not a Number) принадлежит типу number: alert(typeof NaN); Как распознать, что каждая переменная является любым числом, но не NaN и не Infinity, как должна выглядеть функция isNumber?
var a = NaN;
var b = 1;
var c = {};
var d = Infinity;
function isNumber(x) {
// ...
}
alert([isNumber(a), isNumber(b), isNumber(c), isNumber(d)]);
// Должно быть: false, true, false, false
|
А бесконечности?
|
Если не думая, то так: x < 0 || x > 0 || x == 0
причем вариант x < 0 || x > -1 не годится, т. к. null тоже будет числом. |
Цитата:
Riim, твой вариант не срабатывает с Infinity. |
Я имел в виду их пропускать или нет?
|
Цитата:
|
Octane,
то две "m" то одна "i", что за фигня? Цитата:
|
Т.е. isNumber(Number.NEGATIVE_INFINITY) должен быть true?
|
Цитата:
Цитата:
блин без бесконечности все красивее выходило :( |
Понятно, пойду помолчу :)
|
Зачем вообще учитывать Infinity ? Я понимаю NaN.
|
Ну помолчал и будя.
А в чем цимес? isFinite же есть. А если бесконечности должны быть числами, то isNaN есть. |
Да сбили меня этими Infinity :stop:
Вообще вырисовывался такой вариант:
var a = NaN;
var b = 1;
var c = {};
var d = Infinity;
function isNumber(x) {
return ! isNaN(x * 1);
}
alert([isNumber(a), isNumber(b), isNumber(c), isNumber(d)]);
тут isNumber(Infinity) выдает true. В итоге мы пришли к реализации функционала встроенной функции isFinite. |
Интересней реализовать isNaN :)
|
Мой вариант выдает те же результаты и работает быстрей.
|
Riim, в твоем варианте есть ошибка:
function isNumber(x) {
return x < 0 || x > 0 || x == 0;
}
alert(isNumber(false));
Цитата:
function isNumber(x) {
return ! isNaN(x * 1);
}
function isNumber1(x) {
return x < 0 || x > 0 || x === 0;
}
var t1 = new Date().getTime(), i = 100000;
while (i--) {
isNumber(NaN);
isNumber(1);
isNumber({});
}
t1 = new Date().getTime() - t1;
var t2 = new Date().getTime();
i = 100000;
while (i--) {
isNumber1(NaN);
isNumber1(1);
isNumber1({});
}
t2 = new Date().getTime() - t2;
alert([t1, t2]);
|
Опять две "m" :(
|
Octane,
кликай по нику, зачем его писать? |
На копейки, но быстрей (Chrome). Если тестировать только на числах (на практике эта функция в основном их будет принимать), то заметно быстрей.
Куски "x > 0" и "x < 0" можно поменять местами, т. к. на практике положительные числа будут чаще. |
Цитата:
|
:blink: не знал, что:
alert(null * 1) // будет 0 Ушел читать спецификацию… |
[example run]function isNumber1(x) {
return x < 0 || x > 0 || x === 0; } alert(isNumber1('1'))[/example] |
Все варианты трудно учесть, да и смысла не вижу. Например, если функция должна принимать число и получает NaN, то это ошибка и притом вполне возможная, если же она получает, например массив, то это уже неадекватная ошибка. Я пишу код под себя и сам я так точно не ошибусь.
Для чисел я обрабатываю такие варианты: положительные/отрицательные числа, 0, null, undefined, NaN Для не чисел: null, undefined и если нет, то даже typeof/instanceof часто можно не смотреть (тут в каждой ситуации нужно отдельно думать) Этого вполне хватает что бы учесть все !адекватные! ошибки. Предложенный мною вариант все, что мне нужно учитывает, и более быстрого я не вижу. |
typeof x == 'number' && isFinite(x);
|
Наверное, самый железный вариант:
var a = NaN;
var b = 1;
var c = {};
var d = Infinity;
var e = null;
function isNumber(x) {
return Object.prototype.toString.call(x) == "[object Number]" && isFinite(x);
}
alert([isNumber(a), isNumber(b), isNumber(c), isNumber(d), isNumber(e)]);
|
а
var a = NaN;
var b = 1;
var c = {};
var d = Infinity;
var e = null;
function isNumber(x) {
return (typeof x == "number" || x instanceof Number) && isFinite(x);
}
alert([isNumber(a), isNumber(b), isNumber(c), isNumber(d), isNumber(e)]);
UPD: уже вижу недостатки, хоть они и не всегда актуальны |
| Часовой пояс GMT +3, время: 21:07. |