programing

NaN(" ")(공백이 있는 문자열)이 동일한 이유는 무엇입니까?

stoneblock 2023. 8. 27. 08:50

NaN(" ")(공백이 있는 문자열)이 동일한 이유는 무엇입니까?

▁does?, 왜?isNaN(" ")하여 …로 합니다.false,그렇지만isNaN(" x")하여 …로 합니다.true?

텍스트 입력 필드에 대한 수치 연산을 수행하고 있으며 필드가null,""또는NaN누군가 필드에 소수의 공백을 입력하면 세 개 모두에서 유효성 검사가 실패하고, 왜 유효성 검사를 통과하는지 혼란스럽습니다.isNaN끊다

JavaScript는 빈 문자열을 0으로 해석하여 isNAN 테스트를 실패합니다.구문 분석을 사용할 수 있습니다.빈 문자열을 0으로 변환하지 않는 문자열 위에 먼저 삽입합니다.그런 다음 결과가 실패해야 합니다. NAN입니다.

여러분은 이것이 놀랍거나 아닐 수도 있지만, 여기 자바스크립트 엔진의 이상함을 보여줄 몇 가지 테스트 코드가 있습니다.

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 사양 pdf를 여십시오.

문자열에 숫자 구문이 있고 공백 문자를 여러 개 포함할 수 있으면 숫자 유형으로 변환할 수 있습니다.빈 문자열은 0으로 계산됩니다.또한 'Infinity' 문자열이 제공되어야 합니다.

isNaN('Infinity'); // false

사용해 보십시오.

alert(isNaN(parseInt("   ")));

또는

alert(isNaN(parseFloat("    ")));

당면한 문제의 이유로부터

isNaN 함수에 대한 인수가 Number 유형이 아닌 경우 값은 먼저 Number에 강제 적용됩니다.그런 다음 결과 값을 테스트하여 NaN인지 여부를 확인합니다.

동일성에 대한 NaN 비교를 다루는 다음과 같은 포괄적인 답변도 확인할 수 있습니다.

가 JavaScript인지 입니다.NaN

자바스크립트의것 요 : 스크립타때것문같다습니인이핑자의트바다▁i같니습것.' '으로 변환되는 0은 0으로 변환됩니다.'x'그렇지 않음:

alert(' ' * 1); // 0
alert('x' * 1); // NaN

완전히 정답은 아닙니다.

여기서 안토니오 헤일리의 매우 지지받고 받아들여진 답변은 이 과정이 자바스크립트의 절차를 거치는 것이라는 잘못된 가정을 합니다.parseInt함수:

구문 분석을 사용할 수 있습니다.끈 위에...그런 다음 결과가 실패해야 합니다. NAN입니다.

우리는 문자열로 이 진술을 쉽게 반증할 수 있습니다."123abc":

parseInt("123abc")    // 123     (a number...
isNaN("123abc")       // true     ...which is not a number)

이것으로 우리는 자바스크립트의parseInt는 함수반을 반환합니다."123abc"123 그것의 은직아.isNaN함수는 우리에게 말합니다."123abc" 숫자가 아닙니다.

정답

는 ECMA가 어떻게 합니다.isNaN섹션 18.2.3의 점검 작업.

18.2.3isNaN숫자)

isNaN는 수는함입니다.%isNaN%본질적인 목적그 때.isNaN함수는 하나의 인수 번호로 호출되며, 다음 단계를 수행합니다.

  1. 허락하다num무엇입니까?ToNumber(number).
  2. 한다면num이라NaN, 아가다돌다true.
  3. 않으면 그지않면반환으렇을 합니다.false.

ToNumber참조하는 함수는 ECMA스크립트-262의 섹션 7.1.3에도 정의되어 있습니다.여기서는 JavaScript가 이 함수에 전달되는 문자열을 처리하는 방법에 대해 설명합니다.

질문에 제시된 첫 번째 예는 공백 문자만 포함하는 문자열입니다.이 절에는 다음이 명시되어 있습니다.

A StringNumericLiteral되어 있는 은 빈공간또공포공함다간변은다환음니됩로로 됩니다.+0.

" " example 은 따서예문자다은변음환다니됩으로 됩니다.+0숫자입니다.

동일한 섹션에는 다음 사항도 설명되어 있습니다.

이 만문법해수없다면할석이약▁the,▁cannot▁interpret면▁grammar없다▁the▁if수를 해석할 수 없다면,String의 확대로서. 확서로의 로서.StringNumericLiteral그렇다면 결과는ToNumber이라NaN.

해당 섹션에 포함된 모든 점검을 인용하지 않고," x"질문에 주어진 예는 그것이 해석될 수 없기 때문에 위의 조건에 속합니다.StringNumericLiteral." x" 따서로 변됩니다환으로 됩니다.NaN.

정확한 isNumber 함수를 구현하려면 Javascript에서 수행할 수 있는 한 가지 방법이 있습니다. 더글러스 크록포드의 좋은 부분 [105페이지]

var isNumber = function isNumber(value) {
   return typeof value === 'number' && 
   isFinite(value);
}

isNaN("")String to Number 유형 강제 수행

ECMA스크립트 3-5는 연산자 유형에 대해 다음과 같은 반환 값을 정의합니다.

  • 미정의
  • 개체(개체, 개체, 배열)
  • 부울의
  • 번호
  • 기능.

테스트를 기능 본체로 포장하는 것이 좋습니다.

function isNumber (s) {
    return typeof s == 'number'? true
           : typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
           : (typeof s).match(/object|function/)? false
           : !isNaN(s)
}

이 함수는 변수 유형을 테스트하기 위한 것이 아니라 강제 값을 테스트합니다.예를 들어, 부울과 문자열은 숫자로 강제되므로 이 함수를 다음과 같이 부르는 것이 좋습니다.isNumberCoerced()

문자열과 숫자 이외의 형식을 테스트할 필요가 없는 경우 다음 스니펫을 일부 조건으로 사용할 수 있습니다.

if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
    alert("s is a number")

NaN가 아닌" "숫자가아닌"

NaN는 Number Type 의 입니다.

ECMA스크립트의 isNaN()에 대한 정의입니다.

1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.

값을 숫자로 변환해 보십시오.

Number(" ") // 0
Number("x") // NaN
Number(null) // 0

값이 다음과 같은지 확인하려는 경우NaN먼저 숫자 값으로 변환해야 합니다.

정수인지 제대로 확인하려면 다음 기능을 사용하는 것이 좋습니다.

function isInteger(s)
{
   return Math.ceil(s) == Math.floor(s);
}

ㅠㅠisNaN(" ")거짓은 혼란스러운 행동의 일부입니다.isNaN숫자 유형에 대한 비선택적 강제성으로 인한 전역 기능.

MDN에서:

초기 버전의 의가장초버전이후기▁the▁of후이▁since전▁versions▁very▁the▁earliest버기의.isNaN함수 사양입니다. 함수가 아닌 인수에 대한 동작이 혼란스러웠습니다. 있을때에 대한 때.isNaN함수가 Number 유형이 아니므로 값이 먼저 Number에 강제 적용됩니다.그런 다음 결과 값을 테스트하여 다음 값이 다음 값인지 여부를 확인합니다.NaN따라서 숫자 유형에 강제로 지정하면 유효한 비NaN 숫자 값(특히 빈 문자열 및 부울 원시 요소, 강제로 지정하면 숫자 값이 0 또는 1이 됨)이 되는 숫자가 아닌 경우 "false" 반환 값은 예상치 못할 수 있습니다. 예를 들어 빈 문자열은 확실히 "숫자가 아닙니다"입니다.

6에서는 "ECMA" 6이라는 이름의 "EMCA"도됩니다.Number.isNaNMDN:MDN에 과 같습니다.

로▁와 비교하여isNaN() 기능.Number.isNaN()매개 변수를 강제로 숫자로 변환하는 문제가 발생하지 않습니다.이는 일반적으로 변환되는 값을 이제 안전하게 전달할 수 있음을 의미합니다.NaN하만실제같가아은닙치다니가는로지▁as아다▁value▁same니▁but닙과 같은 값이 아닙니다.NaN이것은 또한 형식 번호의 값들, 또한NaN, 아가다돌다true.

유감스럽게도:

6 스크ECMA 트립 6Number.isNaNmethod는 블로그 게시물 - 추악한 JavaScript ES6 NaN 문제 수정에서 설명한 것처럼 고유한 문제가 있습니다.

isNaNfunction은 Number를 인수로 예상하므로 실제 함수 로직이 수행되기 전에 다른 유형(사용자의 경우 문자열)의 인수가 Number로 변환됩니다.(주의:NaN또한 Number 유형의 값입니다!)

Btw. 이것은 모든 내장 함수에 공통적입니다. 특정 유형의 인수가 필요한 경우 실제 인수는 표준 변환 함수를 사용하여 변환됩니다.모든 기본 유형(bool, string, number, object, date, null, defined) 간에 표준 변환이 있습니다.

한표변환의 표준 StringNumber를 사용하여 명시적으로 호출할 수 있습니다.Number()따라서 다음과 같은 것을 확인할 수 있습니다.

  • Number(" ")으로 됩니다.0
  • Number(" x")으로 됩니다.NaN

할 때, 이을고때할의 , 결는과.isNaN함수는 완전히 논리적입니다!

진짜 문제는 표준 문자열에서 숫자로 변환하는 것이 왜 그렇게 작동하느냐는 것입니다.문자열을 숫자로 변환하는 것은 실제로 "123" 또는 "17.5e4"와 같은 숫자 문자열을 동등한 숫자로 변환하기 위한 것입니다.변환은 먼저 초기 공백을 건너뛰고("123"이 유효함) 나머지를 숫자로 구문 분석합니다.숫자("x"가 아님)로 구문 분석할 수 없는 경우 결과는 NaN입니다.그러나 빈 문자열 또는 공백만 있는 문자열은 0으로 변환된다는 명시적인 특수 규칙이 있습니다.그래서 이것이 변환을 설명합니다.

참조: http://www.ecma-international.org/ecma-262/5.1/ #sec-9.3.1

이유는 모르겠지만, 문제를 해결하기 위해서는 항상 확인하기 전에 공백을 잘라낼 수 있습니다.어쨌든 당신은 아마 그것을 하고 싶을 것입니다.

저는 이 문제를 해결하기 위해 이 간단한 기능을 썼습니다.

function isNumber(val) {
     return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};

단순히 숫자(0-9)가 아닌 문자, '-' 또는 '.'가 아닌 문자, 정의되지 않은 문자, null 또는 비어 있지 않은 문자를 확인하고 일치하는 문자가 없으면 true를 반환합니다.:)

다른 사람들이 설명한 것처럼isNaN함수는 빈 문자열을 검증하기 전에 강제로 숫자로 변환하여 빈 문자열을 0(유효한 숫자)으로 변경합니다.하지만, 저는 그것을 발견했습니다.parseInt은 함가반니다됩환을 합니다.NaNas때▁할. 그래서 다음의 이 잘.따라서 다음과 같은 조합이 잘 작동하는 것 같습니다.

if ( isNaN(string) || isNaN(parseInt(string)) ) console.log('Not a number!');

이 검사는 양수, 음수 및 소수점이 있는 숫자에 대해 작동하므로 일반적인 모든 숫자 사례를 포함한다고 생각합니다.

이 기능은 제 시험에서 효과가 있는 것 같았습니다.

function isNumber(s) {
    if (s === "" || s === null) {
        return false;
    } else {
        var number = parseInt(s);
        if (number == 'NaN') {
            return false;
        } else {
            return true;
        }
    }
}

어때

function isNumberRegex(value) {        
    var pattern = /^[-+]?\d*\.?\d*$/i;
    var match = value.match(pattern);
    return value.length > 0 && match != null;
}

JavaScript 기본 제공 기능은 NaN 함수이며, 기본적으로 "동적 유형 연산자"입니다.따라서 (DTC 프로세스 중에) 다음과 같은 단순한 참 | 거짓을 산출할 수 있는 모든 값"", " ", " 000"NaN일 수 없습니다.

제공된 인수가 먼저 다음과 같이 변환됨을 의미합니다.

function isNaNDemo(arg){
   var x = new Number(arg).valueOf();
   return x != x;
}

설명:

함수 본문의 맨 위 줄에서, 우리는 (먼저) 인수를 숫자 객체로 성공적으로 변환하려고 노력하고 있습니다.그리고 (두 번째) 점 연산자를 사용하여 우리는 - 우리 자신의 편의를 위해 - 생성된 객체의 원시적인 가치를 즉시 벗겨냅니다.

두 번째 줄에서, 우리는 이전 단계에서 얻은 값과 NaN이 우주의 어떤 것과도 같지 않다는 사실의 이점을 취하고 있습니다. 예를 들어, 다음과 같습니다.NaN == NaN >> false마지막으로 (불평등을 위해) 자신과 비교하는 것.

이러한 방식으로 함수 반환은 제공된 인수-반환이 숫자 객체(예: NaN)로의 변환 시도가 실패한 경우에만 참이 됩니다.


IsNaNstatic()

그러나 정적 유형 연산자의 경우 - 필요할 경우 - 다음과 같은 훨씬 간단한 함수를 작성할 수 있습니다.

function isNaNstatic(x){   
   return x != x;
}

또한 인수가 명시적으로 NaN 번호가 아닌 경우 거짓으로 반환되도록 DTC를 완전히 피하십시오.따라서 다음 항목에 대해 테스트합니다.

isNaNStatic(" x"); // will return false왜냐하면 그것은 여전히 끈이기 때문입니다.

그나러:isNaNStatic(1/"x"); // will of course return true.를 들면 마찬가지로isNaNStatic(NaN); >> true.

하만반와는 로.isNaN,isNaNStatic("NaN"); >> false왜냐하면 (인수가) 일반 문자열이기 때문입니다.

p.s.: isNaN의 정적 버전은 현대 코딩 시나리오에서 매우 유용할 수 있습니다.그리고 그것이 제가 이 글을 올리는 데 시간을 들인 주요 이유 중 하나일 수도 있습니다.

안부 전해요.

isNAN(<argument>)지정된 인수가 잘못된 숫자인지 여부를 알려주는 함수입니다.isNaNtype은 인수를 숫자 유형으로 캐스팅합니다.인수가 숫자인지 확인하려면 어떻게 해야 합니까?이해주요를 사용해 .$.isNumeric()j에서 합니다.Query에서 기능합니다.

즉, IsNaN(foo)은 isNaN(Number(foo))과 동일합니다.명백한 이유로 모든 숫자를 숫자로 갖는 문자열을 허용합니다.예를 들면.

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

사용합니다.

    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

또는 공백으로 할 때" "이라isNaN하려고 할 수 예를 들어: "" " " " " " " 입니다. 예:

// value = "123 " if (value.match(/\s/) || isNaN(value)) { // do something }

(해석과 같은 변환을 수행하는 다른 함수들 때문에) 숫자 클래스에 특정한 메서드를 갖는 것이 편리하다고 생각합니다.int는 이러한 값 중 일부에 대해 서로 다른 출력을 가지며) 프로토타입 상속을 사용합니다.

Object.assign(Number.prototype, {
  isNumericallyValid(num) {
    if (
      num === null
      || typeof num === 'boolean'
      || num === ''
      || Number.isNaN(Number(num))
    ) {
      return false;
    }
    return true;
  }
});

저는 다음을 사용합니다.

x=(isNaN(parseFloat(x)))? 0.00 : parseFloat(x);

let isNotNumber = val => isNaN(val) || (val.trim && val.trim() === '');

console.log(isNotNumber(' '));
console.log(isNotNumber('1'));
console.log(isNotNumber('123x'));
console.log(isNotNumber('x123'));
console.log(isNotNumber('0'));
console.log(isNotNumber(3));
console.log(isNotNumber('    x'));
console.log(isNotNumber('1.23'));
console.log(isNotNumber('1.23.1.3'));

if(!isNotNumber(3)){
  console.log('This is a number');
}

언급URL : https://stackoverflow.com/questions/825402/why-does-isnan-string-with-spaces-equal-false