2013-08-06 2 views
26

정확히 여기 조건이 사실로 평가되는 이유는 무엇입니까?JavaScript에서 왜 (condition ==! condition)이 true입니까?

var condition = new Boolean(false); 
if (condition == !condition) 
    alert("The more you know..."); 
+2

'조건 ===! 조건'은'false'를 반환합니다. – Praveen

+1

'=='연산자는 다른 타입을 비교할 때 타입 강제 변환을 수행합니다. 객체를 부울과 비교합니다. 유형을 일치 유형으로 강제 변환하는 데 사용 된 알고리즘을 읽으십시오. http://es5.github.io/#x11.9.3 –

+0

이렇게하면 문제가 해결됩니다. http://jsfiddle.net/acdcjunior/zKQ77/3/ – acdcjunior

답변

24

브레이크를 다운 :

var condition = new Boolean(false); 

이 실제로 객체이며, condition.valueOf() === false

!{}{}가 true는 false로 평가

그래서 검사가 (http://www.ecma-international.org/ecma-262/5.1/#sec-9.2 설명) condition.valueOf() == false, 이는 사실입니다.

+2

@Blender'new Boolean (false) .valueOf()'가 거짓이다 – SheetJS

+0

'.valueOf()'는 객체가 아닌 기본 프리미티브를 반환한다. '(새로운 Boolean (false)) === false'. – Blender

+0

docs에서 새로 생성 된 Boolean 객체의 [[PrimitiveValue]] 내부 속성은 ToBoolean (value) .'으로 설정됩니다. 그래서 그것은'조건'이 거짓으로 평가되는 이유를 설명합니다. –

7

정말이 논리적으로 배치되는 스펙을 읽어 단지 도움을 참조로

시작 : 부울 객체가 하지 간주되기 때문에 그런

var x = new Boolean(false); 
var y = !x; 

y = false; 

부울이지만 에버 데이 객체 인 ToBoolean(x)evaluates to true!true evaluates to false

The Abstract Equality Comparison Algorithm

1 라운드 : 단계 형 (Y)는 부울 경우 7

이 비교의 X == ToNumber (Y)의 결과를 반환한다.

y = 0; //ToNumber(false) is 0 

라운드 2 : 9 단계

유형 (x)는 객체 및 유형 (Y) 인 문자열이나 숫자 중 하나 인 경우, 비교 ToPrimitive의 결과 (X 을 반환) == y.

x = false //Basically ends up calling x.valueOf() 

3 라운드 : 유형 (x)는 부울 6

경우 단계는 상기 비교 ToNumber (X) == (Y)의 결과를 반환한다.

x = 0; //ToNumber(false) is 0 

마지막 : 1 단계

(x)를 입력 후,

1 단계 C

타입 (Y)과 동일하면

입력 (X)는 다음 번호,

단계는 X, Y와 동일한 수의 값이 III

경우 C 1 인 경우 true를 반환.

+0

@bfavaretto 아니요, type (x) *는 * 객체이지만, y는 이미 첫 번째 라운드에서 숫자로 변환되었습니다. – Esailija

+0

@bfavaretto 네가 옳다 : D – Esailija

+0

그리고 두 개의 downvotes가있는 이유를 모르겠다! – bfavaretto

4

내가 The Abstract Equality Comparison Algorithm에서 배운 것은 직감을 잊어 버리고 단계를 따르십시오.

객체가 truthy 한, 자신의 부정 false, 그래서 어떤 알고리즘에 들어가는 것은 : 당신이 단계별로 가면

Boolean(false) == false 

, 당신은 얻을 : 당신은 비교하는

Boolean(false) == 0 // Step 7 
false == 0   // Step 9 
0 == 0    // Step 6 
true 
+3

직감을 잊어 버려라. 아마도 최고의 조언을 줄 수있을 것이다. –

23

을 부울 false (RHS)에 대한 객체 (LHS)

[object Boolean] == false 

== ECMAScript를 오퍼레이터에 의해 정의 된 추상적 동일성 비교 알고리즘에 따른 강제 입력을 행한다. 11.9.3 추상 평등 비교 알고리즘

(x는 LHS이고 y는 RHS)의 코드와 관련이 있습니다. 입력 (Y)에 부울 경우

7)는 비교 == ToNumber X (Y)의 결과를 반환한다.

사실은 먼저 부울을 숫자로 변환하려고 시도합니다. 당신이 볼 수 있듯이

[object Boolean] == 0 

, 그것은 재귀 때문에 ==의 동일한 알고리즘을 입력 : 숫자 0false 부울 변환은, 이제 우리는이 있습니다. 그래서 지금 우리는 숫자에 개체를 비교하고 그래서 다음 사항이 적용

9) 유형 (x)는 객체 및 유형 (y는 경우가) 문자열이나 숫자 중 하나이며, 결과를 반환 비교의 ToPrimitive (x) == y.

그래서 이제 개체를 기본 값으로 강제 변환하려고 시도하고 있습니다. 객체에서 호출 9.1 ToPrimitive,에서 :

개체 개체에 대한 기본 값을 반환. 객체의 [[DefaultValue]] 내부 메소드를 호출하여 선택적 힌트 PreferredType을 전달하여 객체의 기본값을 검색합니다. [[DefaultValue]] 내부 메소드의 동작은 8.12.8의 모든 기본 ECMAScript 객체에 대해이 사양에 의해 정의됩니다.

그러면 개체의 [[DefaultValue]]이 필요하다는 것을 알 수 있습니다. 그러면 우리는 8.12.8 [[DefaultValue]]으로, "힌트"를 기대합니다. "힌트"를받지 않았으므로 힌트가 "숫자"인 것처럼 동작합니다. O의 [[의 DefaultValue]] 내부 방법이없는 힌트라고

은, 그것은 힌트가

수 ...

이었다 만약 그렇다면 그 다음에 우리에게 가져다로 동작 동작 :

O의 [된 DefaultValue] 내부 방법은 힌트 번호라고

, 다음 단계가 수행된다 :

  1. valueOf를 인수 "valueOf"를 사용하여 개체 O의 내부 메서드 [[Get]]을 호출 한 결과로 보겠습니다.

  2. IsCallable (valueOf은) 다음에 해당하는 경우

    ,

    가. val을이 값으로 빈 채 인수 목록 인 O와 함께 valueOf의 [[Call]] 내부 메소드를 호출 한 결과가되게합시다.

    b. val이 원시 값이면 val을 반환합니다.

그리고 그것은 수 15.6.4.3 Boolean.prototype.valueOf()

  1. 하자 B에 우리를 가져 오는이 값을 개체에 .valueOf() 메소드를 호출 .

  2. 유형 (B)은 부울이면 B 다른

  3. B.

    하자 유형 (B)는 물체와 [클래스] B의 내부 속성은 "부울"의 값이면 다음, B는 B.

    의 [PrimitiveValue] 내부 속성
  4. 그렇지

    TypeError가 예외를 값이라하자.

  5. 반환 나.

그래서 당신은 개체의 [[PrimitiveValue]]가 반환 3 단계에서 볼 수 있습니다. 즉 15.6.2.1 새로운 부울 (값)

에서 [[PrimitiveValue] 새롭게 구축 Boolean 객체의 내부 속성 ToBoolean로 설정된다 (값)에 우리를 가져온다.

그래서 당신은 당신이 마지막으로 원래 false했다 생성자에 전달 된 값의 ToBoolean 가치를 얻을 수 있습니다 볼 수 있습니다. 그 ToBoolean 값은 분명히 false, 그래서 지금 비교는 이것이다 : 유형부터

false == 0 

여전히 원래의 알고리즘에 6 포인트로 이동합니다, 일치하지 않는 :

(6)) Type (x)이 Boolean이면 ToNumber (x) == y 인 비교 결과를 반환합니다.

이제 부울 false을 숫자로 변환하려고합니다. 이는 위에서 수행 한 것과 유사합니다.

0 == 0 

을 그리고 마지막으로 우리는 유형 일치 비교를 가지고 있고, 그래서 값을 비교하여, 엄격한 === 대응과 동일하게 동작합니다 값 false은 그래서 지금 우리가 가지고있는 값 0로 변환합니다. 그리고 분명히 00과 같기 때문에 true이됩니다. 도덕 이야기의


...이 당신이 "왜"자바 스크립트로 질문 할 때 당신이 얻을 것입니다.

+9

이것은 왜 질문에 대한 최소한의 대답이어야합니다 : D – Esailija

+1

우리는 미친, 우리는 그 단계와 상호 참조를 수행하고 답변을 작성 ... 우리 셋이 시간! – bfavaretto

관련 문제