왜 NaN (“”) (공백이있는 문자열)이 거짓입니까?
자바 스크립트에서, 왜 않는 isNaN(" ")
로 평가 false
하지만, isNaN(" x")
하는 평가 true
?
나는 텍스트 입력 필드에 숫자 작업을 수행하고있어, 나는 필드가있는 경우 확인하고있어 null
, ""
나 NaN
. 누군가 필드에 소수의 공백을 입력하면 세 가지 모두에 대한 유효성 검사가 실패하고 왜 isNaN
검사를 통과했는지 혼란 스럽습니다 .
JavaScript는 빈 문자열을 0으로 해석하여 isNAN 테스트에 실패합니다. 빈 문자열을 0으로 변환하지 않는 문자열에 먼저 parseInt를 사용할 수 있습니다. 그런 다음 isNAN이 실패합니다.
놀랍거나 그렇지 않을 수도 있지만 JavaScript 엔진의 괴짜를 보여주는 테스트 코드가 있습니다.
document.write(isNaN("")) // false
document.write(isNaN(" ")) // false
document.write(isNaN(0)) // false
document.write(isNaN(null)) // false
document.write(isNaN(false)) // false
document.write("" == false) // true
document.write("" == 0) // true
document.write(" " == 0) // true
document.write(" " == false) // true
document.write(0 == false) // true
document.write(" " == "") // false
그래서 이것은
" " == 0 == false
과
"" == 0 == false
그러나
"" != " "
재미있게 보내세요 :)
더 잘 이해하려면 43 페이지의 Ecma-Script spec pdf 를여십시오. "문자열 유형에 적용된 ToNumber"
문자열에 숫자 구문이 있으며 공백 문자를 포함 할 수있는 경우 숫자 형식으로 변환 할 수 있습니다. 빈 문자열은 0으로 평가됩니다. 또한 'Infinity'라는 문자열은
isNaN('Infinity'); // false
다음을 사용하십시오.
alert(isNaN(parseInt(" ")));
또는
alert(isNaN(parseFloat(" ")));
에서 MDN
이 문제에 대한 이유 당신이 직면하고있다
isNaN 함수의 인수가 Number 유형이 아닌 경우 값은 먼저 Number로 강제됩니다. 그런 다음 결과 값을 테스트하여 값이 NaN인지 확인합니다.
평등에 대한 NaN 비교를 다루는 다음의 포괄적 인 답변을 확인하고 싶을 수도 있습니다.
Javascript의 타이핑 때문이라고 생각합니다 .0 ' '
으로 변환되지만 'x'
그렇지는 않습니다.
alert(' ' * 1); // 0
alert('x' * 1); // NaN
정확한 isNumber 함수를 구현하려는 경우 다음은 Javascript 에서 수행하는 한 가지 방법입니다 . Douglas Crockford 의 좋은 부품 [페이지 105]
var isNumber = function isNumber(value) {
return typeof value === 'number' &&
isFinite(value);
}
완전하지 않은 정답
안토니오 헤일리 (Antonio Haley)의 높은지지와 대답 은이 프로세스가 JavaScript의 parseInt
기능 을 겪고 있다고 잘못 가정 합니다.
문자열에 parseInt를 사용할 수 있습니다 ... 결과는 실패합니다 .NAN입니다.
다음 문장을 문자열로 쉽게 반증 할 수 있습니다 "123abc"
.
parseInt("123abc") // 123 (a number...
isNaN("123abc") // true ...which is not a number)
이를 통해 JavaScript의 parseInt
함수가 "123abc"
숫자로 반환 되는 것을 알 수 123
있지만 isNaN
함수는 숫자 "123abc"
가 아니라고 알려줍니다 .
정답
ECMAScript-262는 섹션 18.2.3isNaN
에서 점검이 작동 하는 방식을 정의합니다 .
18.2.3
isNaN
(번호)이
isNaN
함수는%isNaN%
고유 객체입니다. 때isNaN
함수가 하나 개의 인자 번호로 호출, 다음 단계가 수행됩니다
- 하자
num
?ToNumber(number)
.- 인 경우
num
를NaN
반환하십시오true
.- 그렇지 않으면를 반환하십시오
false
.
이 ToNumber
함수가 참조 하는 기능은 ECMAScript-262의 섹션 7.1.3 에도 정의되어 있습니다. 여기에서는 JavaScript가이 함수에 전달 된 문자열을 처리하는 방법에 대해 설명합니다.
질문에 주어진 첫 번째 예는 공백 문자 만 포함하는 문자열입니다. 이 섹션에서는 다음을 설명합니다.
StringNumericLiteral
비어 있거나 공백 만 포함으로 변환됩니다+0
.
따라서 " "
예제 문자열은 +0
숫자 로 변환됩니다 .
같은 섹션에는
문법에서을
String
확장으로 해석 할 수없는 경우StringNumericLiteral
결과는ToNumber
입니다NaN
.
해당 섹션에 포함 된 모든 검사를 인용하지 않으면 " x"
질문에 제공된 예제는로 해석 될 수 없으므로 위의 조건에 해당합니다 StringNumericLiteral
. " x"
따라서로 변환됩니다 NaN
.
왜 그런지 잘 모르겠지만 문제를 해결하기 위해 항상 공백을 다듬기 전에 확인할 수 있습니다. 어쨌든 그렇게하고 싶을 것입니다.
이 함수 isNaN("")
는 문자열 대 숫자 유형 강제 변환 을 수행합니다.
ECMAScript 3-5는 typeof 연산자에 대해 다음과 같은 반환 값을 정의합니다.
- 찾으시는 주소가 없습니다
- 객체 (널, 객체, 배열)
- 부울
- 번호
- 끈
- 함수
함수 본문에서 테스트를 감싸는 것이 좋습니다.
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
This function is not intented to test variable type, instead it tests the coerced value. For instance, booleans and strings are coerced to numbers, so perhaps you may want to call this function as isNumberCoerced()
if there's no need to test for types other than string and number, then the following snippet might be used as part of some condition:
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
I suggest you to use the following function if you really want a proper check if it is an integer:
function isInteger(s)
{
return Math.ceil(s) == Math.floor(s);
}
That isNaN(" ")
is false is part of the confusing behavior of the isNaN
global function due to its coercion of non-numbers to a numeric type.
From MDN:
Since the very earliest versions of the
isNaN
function specification, its behavior for non-numeric arguments has been confusing. When the argument to theisNaN
function is not of type Number, the value is first coerced to a Number. The resulting value is then tested to determine whether it isNaN
. Thus for non-numbers that when coerced to numeric type result in a valid non-NaN numeric value (notably the empty string and boolean primitives, which when coerced give numeric values zero or one), the "false" returned value may be unexpected; the empty string, for example, is surely "not a number."
Note also that with ECMAScript 6, there is also now the Number.isNaN
method, which according to MDN:
In comparison to the global
isNaN()
function,Number.isNaN()
doesn't suffer the problem of forcefully converting the parameter to a number. This means it is now safe to pass values that would normally convert toNaN
, but aren't actually the same value asNaN
. This also means that only values of the type number, that are alsoNaN
, returntrue
.
Unfortunately:
Even the ECMAScript 6 Number.isNaN
method has its own issues, as outlined in the blog post - Fixing the ugly JavaScript and ES6 NaN problem.
The isNaN
function expects a Number as its argument, so arguments of any other type (in your case a string) will be converted to Number before the actual function logic is performed. (Be aware that NaN
is also a value of type Number!)
Btw. this is common for all built-in functions - if they expect an argument of a certain type, the actual argument will be converted using the standard conversion functions. There are standard conversions between all the basic types (bool, string, number, object, date, null, undefined.)
The standard conversion for String
to Number
can be invoked explicit with Number()
. So we can see that:
Number(" ")
evaluates to0
Number(" x")
evaluates toNaN
Given this, the result of the isNaN
function is completely logical!
The real question is why the standard String-to-Number conversion works like it does. The string-to-number conversion is really intended to convert numeric strings like "123" or "17.5e4" to the equivalent numbers. The conversion first skips initial whitespace (so " 123" is valid) and then tries to parse the rests as a number. If it is not parseable as a number ("x" isn't) then the result is NaN. But there is the explicit special rule that a string which is empty or only whitespace is converted to 0. So this explains the conversion.
Reference: http://www.ecma-international.org/ecma-262/5.1/#sec-9.3.1
As other explained the isNaN
function will coerce the empty string into a number before validating it, thus changing an empty string into 0 (which is a valid number). However, I found that the parseInt
function will return NaN
when trying to parse an empty string or a string with only spaces. As such the following combination seems to be working well:
if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');
This check will work for positive numbers, negative numbers and numbers with a decimal point, so I believe it covers all common numerical cases.
This function seemed to work in my tests
function isNumber(s) {
if (s === "" || s === null) {
return false;
} else {
var number = parseInt(s);
if (number == 'NaN') {
return false;
} else {
return true;
}
}
}
What about
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
I wrote this quick little function to help solve this problem.
function isNumber(val) {
return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};
It simply checks for any characters that aren't numeric (0-9), that aren't '-' or '.', and that aren't undefined, null or empty and returns true if there's no matches. :)
The JavaScript built-in isNaN function, is - as should be expected by default - a "Dynamic Type Operator". Therefore all values which (during the DTC process) may yield a simple true | false such as "", " ", " 000"
, cannot be NaN.
Meaning that the argument supplied will first undergo a conversion as in:
function isNaNDemo(arg){
var x = new Number(arg).valueOf();
return x != x;
}
Explanation:
In the top line of the function body, we are (first) trying to successfully convert the argument into a number object. And (second), using the dot operator we are - for our own convenience - immediately stripping off, the primitive value of the created object.
In the second line, we are taking the value obtained in the previous step, and the advantage of the fact that NaN is not equal to anything in the universe, not even to itself, e.g.: NaN == NaN >> false
to finally compare it (for inequality) with itself.
This way the function return will yield true only when, and only if, the supplied argument-return, is a failed attempt of conversion to a number object, i.e., a not-a-number number; e.g., NaN.
isNaNstatic( )
However, for a Static Type Operator - if needed and when needed - we can write a far simpler function such as:
function isNaNstatic(x){
return x != x;
}
And avoid the DTC altogether so that if the argument is not explicitly a NaN number, it will return false. Wherefore, testing against the following:
isNaNStatic(" x"); // will return false
because it's still a string.
However: isNaNStatic(1/"x"); // will of course return true.
as will for instance isNaNStatic(NaN); >> true
.
But contrary to isNaN
, the isNaNStatic("NaN"); >> false
because it (the argument) is an ordinary string.
p.s.: The static version of isNaN can be very useful in modern coding scenarios. And it may very well be one of the main reasons I took my time for posting this.
Regards.
isNAN(<argument>)
is a function to tell whether given argument is illegal number. isNaN
typecasts the arguments into Number type. If you want to check if argument is Numeric or not? Please use $.isNumeric()
function in jQuery.
That is, isNaN(foo) is equivalent to isNaN(Number(foo)) It accepts any strings having all numerals as numbers for obvious reasons. For ex.
isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true
I use this
function isNotANumeric(val) {
if(val.trim && val.trim() == "") {
return true;
} else {
return isNaN(parseFloat(val * 1));
}
}
alert(isNotANumeric("100")); // false
alert(isNotANumeric("1a")); // true
alert(isNotANumeric("")); // true
alert(isNotANumeric(" ")); // true
NaN
!== "not a number"
NaN
is a value of Number Type
this is a definition of isNaN() in ECMAScript
1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.
Try to convert any value to Number.
Number(" ") // 0
Number("x") // NaN
Number(null) // 0
If you want to determine if the value is NaN
, you should try to convert it to a Number value firstly.
When checking if certain string value with whitespace or " "
is isNaN
maybe try to perform string validation, example :
// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }
참고URL : https://stackoverflow.com/questions/825402/why-does-isnan-string-with-spaces-equal-false
'Programing' 카테고리의 다른 글
grep에서 반환되는 결과 수를 어떻게 제한합니까? (0) | 2020.06.08 |
---|---|
ssh-keygen -t rsa를 자동화하여 암호를 요구하지 않습니다. (0) | 2020.06.08 |
누군가 Microsoft Unity를 설명 할 수 있습니까? (0) | 2020.06.08 |
항목의 순서에 관계없이 동일성을 위해 두 컬렉션을 비교 (0) | 2020.06.08 |
복사 생성자 비활성화 (0) | 2020.06.08 |