정확히 여기 조건이 사실로 평가되는 이유는 무엇입니까?JavaScript에서 왜 (condition ==! condition)이 true입니까?
var condition = new Boolean(false);
if (condition == !condition)
alert("The more you know...");
정확히 여기 조건이 사실로 평가되는 이유는 무엇입니까?JavaScript에서 왜 (condition ==! condition)이 true입니까?
var condition = new Boolean(false);
if (condition == !condition)
alert("The more you know...");
브레이크를 다운 :
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
, 이는 사실입니다.
정말이 논리적으로 배치되는 스펙을 읽어 단지 도움을 참조로
시작 : 부울 객체가 하지 간주되기 때문에 그런
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를 반환.
@bfavaretto 아니요, type (x) *는 * 객체이지만, y는 이미 첫 번째 라운드에서 숫자로 변환되었습니다. – Esailija
@bfavaretto 네가 옳다 : D – Esailija
그리고 두 개의 downvotes가있는 이유를 모르겠다! – bfavaretto
내가 The Abstract Equality Comparison Algorithm에서 배운 것은 직감을 잊어 버리고 단계를 따르십시오.
객체가 truthy 한, 자신의 부정 false
, 그래서 어떤 알고리즘에 들어가는 것은 : 당신이 단계별로 가면
Boolean(false) == false
, 당신은 얻을 : 당신은 비교하는
Boolean(false) == 0 // Step 7
false == 0 // Step 9
0 == 0 // Step 6
true
직감을 잊어 버려라. 아마도 최고의 조언을 줄 수있을 것이다. –
을 부울 false
(RHS)에 대한 객체 (LHS)
[object Boolean] == false
==
ECMAScript를 오퍼레이터에 의해 정의 된 추상적 동일성 비교 알고리즘에 따른 강제 입력을 행한다. 11.9.3 추상 평등 비교 알고리즘
(x는 LHS이고 y는 RHS)의 코드와 관련이 있습니다. 입력 (Y)에 부울 경우
7)는 비교 == ToNumber X (Y)의 결과를 반환한다.
사실은 먼저 부울을 숫자로 변환하려고 시도합니다. 당신이 볼 수 있듯이
[object Boolean] == 0
, 그것은 재귀 때문에 ==
의 동일한 알고리즘을 입력 : 숫자 0
에 false
부울 변환은, 이제 우리는이 있습니다. 그래서 지금 우리는 숫자에 개체를 비교하고 그래서 다음 사항이 적용
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] 내부 방법은 힌트 번호라고, 다음 단계가 수행된다 :
valueOf를 인수 "valueOf"를 사용하여 개체 O의 내부 메서드 [[Get]]을 호출 한 결과로 보겠습니다.
IsCallable (valueOf은) 다음에 해당하는 경우
,가. val을이 값으로 빈 채 인수 목록 인 O와 함께 valueOf의 [[Call]] 내부 메소드를 호출 한 결과가되게합시다.
b. val이 원시 값이면 val을 반환합니다.
그리고 그것은 수 15.6.4.3 Boolean.prototype.valueOf()
하자 B에 우리를 가져 오는이 값을 개체에
.valueOf()
메소드를 호출 .유형 (B)은 부울이면 B 다른
B.
하자 유형 (B)는 물체와 [클래스] B의 내부 속성은 "부울"의 값이면 다음, B는 B.의 [PrimitiveValue] 내부 속성- 그렇지
TypeError가 예외를 값이라하자.
반환 나.
그래서 당신은 개체의 [[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
로 변환합니다. 그리고 분명히 0
은 0
과 같기 때문에 true
이됩니다. 도덕 이야기의
...이 당신이 "왜"자바 스크립트로 질문 할 때 당신이 얻을 것입니다.
이것은 왜 질문에 대한 최소한의 대답이어야합니다 : D – Esailija
우리는 미친, 우리는 그 단계와 상호 참조를 수행하고 답변을 작성 ... 우리 셋이 시간! – bfavaretto
'조건 ===! 조건'은'false'를 반환합니다. – Praveen
'=='연산자는 다른 타입을 비교할 때 타입 강제 변환을 수행합니다. 객체를 부울과 비교합니다. 유형을 일치 유형으로 강제 변환하는 데 사용 된 알고리즘을 읽으십시오. http://es5.github.io/#x11.9.3 –
이렇게하면 문제가 해결됩니다. http://jsfiddle.net/acdcjunior/zKQ77/3/ – acdcjunior