JavaScript에서 "0"이 false 인 이유는 있지만 'if'로 테스트 할 때 자체적으로 false가 아닌 이유는 무엇입니까?


232

다음은 "0"Javascript에서 잘못된 것을 보여줍니다 .

>>> "0" == false
true

>>> false == "0"
true

그렇다면 다음은 왜 인쇄 "ha"됩니까?

>>> if ("0") console.log("ha")
ha

47
"0"문자열이며 비어 있지 않으므로 true로 평가됩니다.
디지털 비행기

8
"0" === false [...] false

3
자바 스크립트에서 Angus Croll의 기사 진실을 확인하십시오. javascriptweblog.wordpress.com/2011/02/07/…
timrwood

8
'0'==false그러나 '0'은 잘못된 값이 아닙니다 (예 : 자바 스크립트가 이상 할 수 있음)
Linsey

5
@Linsey : "거짓"과 "거친"은 값이 부울로 변환되는 방법을 설명하기위한 것입니다. 당신이 두 값을 비교하면 ==, 그들은 결코 이 적용되지 않도록, 논리 값으로 변환되지 얻을. (변환 규칙은 숫자로 변환하는 것을 선호하는 것 같습니다.)
millimoose

답변:


251

그 이유는 명시 적으로 할 때 "0" == false양쪽이 숫자로 변환 된 다음 비교가 수행 되기 때문 입니다.

할 때 : if ("0") console.log("ha")문자열 값을 테스트합니다. 비어 있지 않은 문자열입니다 true빈 문자열 인 반면, false.

같음 (==)

두 피연산자가 같은 유형아닌 경우 JavaScript는 피연산자를 변환 한 다음 엄격한 비교를 적용합니다. 피연산자 중 하나가 숫자이거나 부울 인 경우 피연산자는 가능한 경우 숫자로 변환됩니다. 그렇지 않으면 피연산자 중 하나가 string 이면 다른 피연산자는 가능한 경우 문자열로 변환됩니다. 두 피연산자가 모두 객체 인 경우 , JavaScript는 피연산자가 메모리에서 동일한 객체를 참조 할 때 동일한 내부 참조를 비교합니다.

( Mozilla Developer Network의 비교 연산자 에서)


348

문제를 표시하는 표 :

진실한 진술

그리고 == 자바 스크립트에서 모든 객체 유형의 진실한 비교

이야기 사용의 도덕 === 온전함을 나타내는 엄격한 평등

테이블 생성 크레딧 : https://github.com/dorey/JavaScript-Equality-Table


2
이 값의 또 다른 주문 훨씬 더 의미가 있습니다 gist.github.com/kirilloid/8165660
kirilloid

3
이제부터 누군가가 엄격한 비교 연산자를 사용하지 않는다고 말하면, 나는이 테이블을보고 그를 울게 할 것입니다. 그래도 개념을 이해했는지 확실하지 않습니다 NaN. 내 말은, typeof NaN // number하지만, NaN === NaN // false흠 ...,
유스 Romijn

4
내 친구가 f.cl.ly/items/3b0q1n0o1m142P1P340P/javascript_equality.html을 만들었습니다. 위와 동일한 그래프이지만 읽기가 더 쉽습니다.
Lucy Bain

@JustusRomijn은 나타내는 여러 값이 NaN있으므로 2 NaN을 비교할 때 값이 다릅니다 (제 생각에는). 여기 에서 첫 번째 인용문을 읽으 십시오 .
cychoi

4
이 테이블에는 실수가 있습니다. 어느 쪽도하지 ==않고 ===연산자가 [], {}, [[]], [0][1]값이 true로 평가하지 않습니다. 내 말은 [] == []하고 [] === []도 거짓.
Herbertusz

38

사양에 따릅니다.

12.5 if 문 
.....

2. ToBoolean (GetValue (exprRef))이 true이면 
ㅏ. 첫 번째 진술을 평가 한 결과를 반환하십시오.
3. 그렇지 않으면 
....

사양에 따라 ToBoolean은

추상 작업 ToBoolean은 인수를 표 11에 따라 Boolean 유형의 값으로 변환합니다.

그리고 그 테이블은 문자열에 대해 이것을 말합니다 :

여기에 이미지 설명을 입력하십시오

인수가 빈 문자열 (길이가 0) 인 경우 결과는 false입니다. 그렇지 않으면 결과는 사실이다

이제 "0" == false평등 연산자를 읽어야 하는 이유를 설명하기 위해 추상 연산에서 값을 가져 오는 GetValue(lref)오른쪽과 동일합니다.

이 관련 부분을 다음과 같이 설명합니다.

IsPropertyReference (V)이면 
ㅏ. HasPrimitiveBase (V)가 false 인 경우 기본 [[Get]] 내부 메소드가되도록하고 그렇지 않으면 get
아래에 정의 된 특별한 [[Get]] 내부 메소드 여야합니다. 
비. base를이 값으로 사용하여 get internal 메소드를 호출하고 전달한 결과를 리턴합니다.
인수에 대한 GetReferencedName (V)

즉, 문자열에는 기본 getbase가 있는데,이 함수는 내부 get 메소드를 호출하고 false로 보입니다.

GetValue 연산 use를 사용하여 사물 ==을 평가하려면 ToBoolean을 사용 하여 평가하려는 경우 ===( "strict"항등 연산자라고도 함)


"a string has a primitive base, which calls back the internal get method and ends up looking false"이것은 모든 문자열에 해당됩니까?
aziz punjani

@Interstellar_Coder Section 8.12.3: [[Get]] (P)는 작동 방식을 설명합니다. 문자열이 0 인 경우에만 해당됩니다. 결과적으로 GetOwnProperty"내가 무엇이든"이 데이터 속성임을 확인한 다음 그 값을 다시 반환하는 다른 내부 호출을 많이 수행하기 때문 입니다. 이것이 "0"이 거짓이고 "blah"가 참인 이유입니다. Yahoo 개발자 극장에서 Douglas Crockford의 비디오 중 일부를 확인하십시오. 그는 JavaScript의 "truthyness"를 저보다 덜 복잡하게 설명합니다. "거짓"과 "거짓"의 의미를 이해하면 Bobince의 대답을 바로 이해할 수 있습니다.
시크릿

1
사양은 어디서 찾을 수 있습니까?
user985366 2016 년

12

문자열 "0"이 거짓 인 PHP입니다 (거짓 사용시 부울 컨텍스트). JavaScript에서 비어 있지 않은 모든 문자열은 진실입니다.

트릭은 ==부울에 대해 부울 컨텍스트에서 평가하지 않고 숫자로 변환하고 문자열의 경우 10 진수로 구문 분석하여 수행되는 것입니다. 그래서 당신 0은 진실 부울 대신 숫자를 얻습니다 true.

이것은 언어 디자인이 실제로 좋지 않은 부분이며 불행한 ==연산자 를 사용하지 않는 이유 중 하나입니다 . ===대신 사용하십시오 .


7
// I usually do this:

x = "0" ;

if (!!+x) console.log('I am true');
else      console.log('I am false');

// Essentially converting string to integer and then boolean.

4

주위에 당신의 따옴표 0 는 문자열로 만들어 , 이는 사실로 평가됩니다.

따옴표를 제거하면 작동합니다.

if (0) console.log("ha") 

"작동하게 만드는"방법이 아니라 "왜 그렇게 행동 하는가?"
nonopolarity


1

"if"표현은 진위 여부를 테스트하는 반면, 이중 같음은 유형 독립적 인 동등성을 테스트합니다. 다른 사람들이 지적했듯이 끈은 항상 진실합니다. 이중 동일성이 두 피연산자 모두에 대해 진실성을 테스트 한 다음 결과를 비교하는 경우 직관적으로 가정 한 결과를 얻을 수 있습니다 ("0" == true) === true. Doug Crockford가 자신의 뛰어난 JavaScript 에서 " 좋은 부분 (Good Parts )"에서 "[== 피연산자의 유형을 강제하는] 규칙은 복잡하고 잊을 수없는 규칙입니다 .... 피연산자 중 하나가 다른 피연산자와 일치하도록 유형 강제되어 있고 "0"은 숫자 0으로 해석된다고 말하면 충분합니다.


1

== 같음 연산자는 인수를 숫자로 변환 한 후 평가합니다. 문자열 제로 "0"Number 데이터 유형 및 부울 false로 변환되고, 그래서 번호 0으로 변환되고, 그래서

"0" == false // true

`에도 동일하게 적용됩니다.

false == "0" //true

=== 엄격한 동등성 검사는 원래 데이터 유형의 인수를 평가합니다.

"0" === false // false, because "0" is a string and false is boolean

동일

false === "0" // false

if("0") console.log("ha");

문자열 "0"은 (는) 인수와 비교하지 않으며 문자열은 인수와 비교할 때까지 또는 그렇지 않으면 실제 값입니다. 정확히 같다

if(true) console.log("ha");

그러나

if (0) console.log("ha"); // empty console line, because 0 is false

`


1

이는 JavaScript가 부울 컨텍스트와 코드에서 유형 강제 변환을 사용하기 때문입니다

if ("0") 

부울 컨텍스트에서 true로 강제됩니다.

Javascript에는 부울 컨텍스트에서 true로 강제 변환되는 ify 값이 있으므로 if 블록은 다음과 같이 실행됩니다.

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

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