왜 null> = 0 && null <= 0`이지만 null == 0이 아닌 이유는 무엇입니까?


142

내가 루틴을 작성했다고 단위의 유형 인 경우 (1)에 의한 변수의 값 number변수가 처음이 아닌 경우 변수, 및 양수인 0 null또는 undefined.

첫 번째 구현은 v >= 0 ? v += 1 : v = 0숫자가 아닌 것이 산술 표현식을 거짓으로 만들 것이라고 생각했기 때문에 이루어졌지만 null >= 0true로 평가 된 이후로 잘못되었습니다 . 그런 다음 null0과 같은 동작을 배우고 다음 표현식이 모두 true로 평가됩니다.

  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1 / null === Infinity
  • Math.pow(42, null) === 1

물론 null0이 아닙니다 null == 0. false로 평가됩니다. 이것은 겉보기에 타우 톨 로지 된 표현을 (v >= 0 && v <= 0) === (v == 0)거짓으로 만듭니다.

null실제로 0이 아니지만 왜 0과 같습니까?


3
그는 Javascript에 대해 이야기하고 있습니다. 귀하의 예는 PHP입니다. PHP에서 operator ==는 특별한 방식으로 값을 비교합니다. "10"== "1e1"과 같은 정말 미친 비교를 할 수 있습니다 (사실). operator ===를 사용하면 유형뿐만 아니라 값이 일치하는지 확인하기 때문에 완전히 다른 결과를 얻습니다. : 아웃이 링크를 확인 php.net/manual/en/language.operators.comparison.php
Pijusn

PHP '=='연산자는 실제로 "특별한"방식으로 작동합니다.
2 비트 연금술사

요구 사항이 0이 아닌 1에서 계산을 시작하는 경우에는 처음에 null또는 undefined다음 중 하나에 해당하는 카운터를 늘리는 간결한 방법이 있습니다 .c = -~c // Results in 1 for null/undefined; increments if already a number
Ates Goral

1
undefined초기화되지 않은 변수에 대한 변수 값입니다. null반면에는 빈 객체 값이며 숫자와 혼합해서는 안됩니다. null숫자와 결합되어서는 안되므로 null은 숫자처럼 동작하지 않아도됩니다.
Matthew

1
@AtesGoral-간결하지만 명확하지 않습니다. 사람들에게 분명하지 않은 일을 할 때마다 코드의 기능을 설명하는 주석을 추가하십시오. 대부분의 상황에서 나는 그것이 작은 성능 향상을 위해 명확성을 교환한다는 점을 고려할 때 "초기 최적화"라고 생각합니다.
ToolmakerSteve

답변:


207

당신의 실제 질문은 다음과 같습니다.

왜:

null >= 0; // true

그러나:

null == 0; // false

실제로 일어나는 것은 같거나 큰 연산자 ( >=) ToPrimitive힌트 유형으로 유형 강제 변환 ( )을 수행 한다는 것 입니다 Number. 실제로 모든 관계 연산자에는이 동작이 있습니다.

null등호 연산자 ( ==) 가 특별한 방식으로 처리 합니다. 간단히 말해 다음과 같이 강제 됩니다 undefined.

null == null; // true
null == undefined; // true

값은 같은 false, '', '0',과 [], 그들 모두 0으로 숫자 형식의 강제 적용을 강요하고 있습니다.

이 프로세스의 내부 세부 사항은 추상 동등 비교 알고리즘추상 관계 비교 알고리즘에서 볼 수 있습니다.

요약해서 말하자면:

  • 관계 비교 : 두 값이 모두 문자열 유형이 아닌 경우 두 값 ToNumber모두에서 호출됩니다. 이것은 +앞에 null 을 추가하는 것과 동일 합니다 0.

  • 평등 비교 : ToNumber문자열, 숫자 및 부울 만 호출 합니다.


1
Hi CMS는 설명에 따라 null 프리미티브가 0이므로 0> = 0은 true를 반환하고 ==는 false를 반환하지만 ecma 알고리즘에 따라 Type (x)가 Object이고 Type (y)가 String 또는 Number 인 경우 비교 ToPrimitive의 결과를 반환 (x)를 == y.then이의 그것은 나를 설명 true.please 반환해야합니다
바라 스 muppa

나에 대한 답변은 제공하지 않습니다 - null is treated in a special way by the Equals Operator (==). In a brief, it only coerces to undefined:- 무엇을? 왜 설명 할 수 있습니까 null >= 0? :)
Andrey Deineko 2016 년

@bharathmuppa @ andrey-deineko : CMS의 나머지 답변은 다음과 같습니다 . 3 지점에서 설명하는 추상 관계 비교 알고리즘 입니다. 두 값이 모두 String 유형이 아닌 경우 ToNumber가 모두 호출됩니다. 이것은 +앞에 null 을 추가하는 것과 동일 합니다 0. 평등은 문자열, 숫자 및 부울에서 ToNumber 만 호출합니다.
Michael Liquori

7
좋은 설명이지만 마음에 들지 않습니다. 모든 언어에서 (x == 0 || x> 0)은 (x> = 0)과 같아야합니다. 자바 스크립트는 멍청한 언어입니다.
존 헨켈

1
그것은 실제로 (수학적으로 잘못 되었기 때문에) 실제로 스펙의 버그이며 수백만 개의 웹 사이트가 null 비교에 의존하기 때문에 그것에 대해 아무런 관련이 없습니다 ^^ '
mahieddine

14

문제의 가시성을 더 향상시키기 위해 질문을 확장하고 싶습니다.

null >= 0; //true
null <= 0; //true
null == 0; //false
null > 0;  //false
null < 0;  //false

말이되지 않습니다. 인간 언어와 마찬가지로 이러한 것들도 마음으로 배워야합니다.


1
위에서 설명한 것처럼 ==가 null을 처리하는 방법을 예외로 설명 할 수 있습니다. 그렇지 않으면 모든 경우에 Number (nulll)를 사용하여 null이 0으로 변환됩니다.
Sourabh Ranka

5

JavaScript에는 엄격한 변환과 형식 변환 비교가 있습니다

null >= 0;사실이지만 (null==0)||(null>0)거짓

null <= 0;사실이지만 (null==0)||(null<0)거짓

"" >= 0 또한 사실이다

관계형 추상 비교 (<=,> =)의 경우, 피연산자는 먼저 비교 전에 프리미티브로 변환 된 다음 동일한 유형으로 변환됩니다.

typeof null returns "object"

type이 객체 javascript 인 경우 객체를 문자열 화하려고 시도하면 (예 : null) 다음 단계가 수행됩니다 ( ECMAScript 2015 ).

  1. PreferredType통과되지 않은 경우 hint"기본값"으로 설정하십시오.
  2. 경우 다른 PreferredTypehint문자열,하자 hint"문자열"합니다.
  3. 그밖에 PreferredType입니다 hint번호는하자 hint"번호"합니다.
  4. 하자 exoticToPrimGetMethod(input, @@toPrimitive).
  5. ReturnIfAbrupt(exoticToPrim).
  6. exoticToPrim정의되지 않은 경우
    a) 결과를이라고합시다 Call(exoticToPrim, input, «hint»).
    b) ReturnIfAbrupt(result).
    c) Type(result)Object가 아닌 경우 결과를 반환합니다.
    d) TypeError 예외를 던집니다.
  7. 경우 hint"기본"입니다하자 hint"수"를합니다.
  8. 을 반환 OrdinaryToPrimitive(input,hint)합니다.

힌트에 허용되는 값은 "default", "number"및 "string"입니다. Date 객체는 내장 된 ECMAScript 객체 중에서 고유하며 "default"를 "string"과 동일하게 취급합니다. 다른 모든 내장 ECMAScript 객체는 "default"를 "number"와 동등한 것으로 간주합니다 . ( ECMAScript 20.3.4.45 )

그래서 null0으로 변환 한다고 생각 합니다.


1

나는 같은 문제가 있었다!. 현재 내 유일한 해결책은 분리하는 것입니다.

var a = null;
var b = undefined;

if (a===0||a>0){ } //return false  !work!
if (b===0||b>0){ } //return false  !work!

//but 
if (a>=0){ } //return true !

대신 다음을 수행하는 것이 더 명확 할 수 있습니다 if (a!=null && a>=0).. 이것은 단순히 >=스스로 수행하지 않는 이유를 명확하게한다 . "a는 null 일 수도 있고 정의되지 않은 것도 '== null'일 수도있다."
ToolmakerSteve

0
console.log( null > 0 );  // (1) false
console.log( null == 0 ); // (2) false
console.log( null >= 0 ); // (3) true

수학적으로는 이상합니다. 마지막 결과는 "null이 0보다 크거나 같다"는 것이므로 위의 비교 중 하나에서 true 여야하지만 둘 다 false입니다.

그 이유는 평등 검사 ==와 비교가 > < >= <=다르게 작동하기 때문입니다. 비교는 null을 숫자로 변환하여로 처리합니다 0. 그렇기 때문에 (3) null >= 0true(1) null > 0false입니다.

반면에, 동등 검사 ==에 대한 undefined과는 null어떠한 변환없이, 그들은 서로 동일하고 다른 동일 아무것도하지 않는, 그런 것을 정의된다. 그렇기 때문에 (2) null == 0false입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.