JavaScript에서 왜 2 == [2]입니까?
최근 2 == [2]
에 JavaScript에서 발견했습니다 . 이 기발한 결과는 몇 가지 흥미로운 결과를 낳습니다.
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
마찬가지로 다음과 같이 작동합니다.
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
여전히 낯선 사람이라도, 이것은 잘 작동합니다.
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
이러한 동작은 모든 브라우저에서 일관된 것처럼 보입니다.
이것이 왜 언어 기능인지 아십니까?
이 "기능"의 결과는 다음과 같습니다.
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
이러한 예는 jimbojw에 의해 발견되었다 http://jimbojw.com 명성뿐만 아니라 walkingeyerobot .
ECMA 사양 (문제에 대한 ECMA-262, 3 판 : 11.9.3, 9.1, 8.6.2.6의 관련 섹션)에서 비교 알고리즘을 찾을 수 있습니다.
관련된 추상 알고리즘을 JS로 다시 변환하면 평가할 때 2 == [2]
기본적으로 다음과 같은 결과 가 발생 합니다.
2 === Number([2].valueOf().toString())
여기서 valueOf()
for 배열은 배열 자체를 반환하고 단일 요소 배열의 문자열 표현은 단일 요소의 문자열 표현입니다.
이것은 또한 [[[[[[[2]]]]]]].toString()
여전히 문자열 인 세 번째 예를 설명 합니다 2
.
보시다시피, 많은 배후의 마술이 관련되어 있기 때문에 일반적으로 엄격한 항등 연산자 만 사용합니다 ===
.
속성 이름은 항상 문자열이므로 첫 번째와 두 번째 예는 따르기가 더 쉽습니다.
a[[2]]
에 해당
a[[2].toString()]
그냥
a["2"]
배열 키가 발생하기 전에 숫자 키도 속성 이름 (예 : 문자열)으로 처리됩니다.
==
연산자 의 암시 적 유형 변환 때문입니다 .
[2]는 숫자와 비교할 때 숫자는 2로 변환됩니다. +
[2] 에서 단항 연산자를 사용해보십시오 .
> +[2]
2
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
방정식의 오른쪽에는 a [2]가 있습니다.이 값은 값이 2 인 숫자 유형을 반환합니다. 왼쪽에서 먼저 단일 객체가 2 인 새 배열을 만듭니다. 그런 다음 a [( 배열은 여기에 있습니다)]. 이것이 문자열 또는 숫자로 평가되는지 확실하지 않습니다. 2 또는 "2". 먼저 문자열을 살펴 보겠습니다. 나는 a [ "2"]가 새로운 변수를 만들고 null을 리턴 할 것이라고 믿는다. null! == 2. 따라서 실제로 암시 적으로 숫자로 변환한다고 가정합니다. a [2]는 유형 (따라서 === 작동)과 값에서 2와 2의 일치를 반환합니다. a [value]는 문자열이나 숫자를 기대하기 때문에 배열을 숫자로 암시 적으로 변환한다고 생각합니다. 숫자가 우선 순위가 높은 것 같습니다.
참고로, 누가 그 우선 순위를 결정하는지 궁금합니다. [2]에 첫 번째 항목 인 숫자가 있기 때문에 숫자로 변환됩니까? 또는 배열을 배열에 전달할 때 배열을 먼저 숫자로 변환 한 다음 문자열로 바꾸려고합니다. 누가 알아?
var a = { "abc" : 1 };
a[["abc"]] === a["abc"];
이 예에서는 abc라는 멤버를 사용하여 a라는 객체를 만듭니다. 방정식의 오른쪽은 매우 간단합니다. a.abc와 같습니다. 왼쪽이 먼저 [ "abc"]의 리터럴 배열을 만듭니다. 그런 다음 새로 생성 된 배열을 전달하여 객체에서 변수를 검색합니다. 이것은 문자열을 기대하기 때문에 배열을 문자열로 변환합니다. 이제는 1과 동일한 a [ "abc"]로 평가됩니다. 1과 1은 같은 유형 (이는 ===가 작동하는 이유)과 동일한 값입니다.
[[[[[[[2]]]]]]] == 2;
이것은 단지 암묵적인 변환입니다. 유형이 일치하지 않기 때문에이 상황에서는 === 작동하지 않습니다.
이 ==
경우 Doug Crockford 는 항상을 사용하는 것이 좋습니다 ===
. 암시 적 유형 변환을 수행하지 않습니다.
의 예에서는 ===
등식 연산자가 호출되기 전에 암시 적 형식 변환이 수행됩니다.
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
흥미 롭습니다. 실제로 [0]은 사실과 거짓이 아닙니다. 실제로
[0] == true // false
if () 연산자를 처리하는 자바 스크립트의 재미있는 방법입니다.
한 항목의 배열은 항목 자체로 취급 될 수 있습니다.
이것은 오리 타이핑 때문입니다. "2"== 2 == [2] 이후 가능합니다.
To add a little detail to the other answers... when comparing an Array
to a Number
, Javascript will convert the Array
with parseFloat(array)
. You can try it yourself in the console (eg Firebug or Web Inspector) to see what different Array
values get converted to.
parseFloat([2]); // 2
parseFloat([2, 3]); // 2
parseFloat(['', 2]); // NaN
For Array
s, parseFloat
performs the operation on the Array
's first member, and discards the rest.
Edit: Per Christoph's details, it may be that it is using the longer form internally, but the results are consistently identical to parseFloat
, so you can always use parseFloat(array)
as shorthand to know for sure how it will be converted.
You are comparing 2 objects in every case.. Dont use ==, if you are thinking of comparison, you are having === in mind and not ==. == can often give insane effects. Look for the good parts in the language :)
Explanation for the EDIT section of the question:
1st Example
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
First typecast [0] to a primitive value as per Christoph's answer above we have "0" ([0].valueOf().toString()
)
"0" == false
Now, typecast Boolean(false) to Number and then String("0") to Number
Number("0") == Number(false)
or 0 == 0
so, [0] == false // true
As for if
statement, if there is not an explicit comparison in the if condition itself, the condition evaluates for truthy values.
There are only 6 falsy values: false, null, undefined, 0, NaN and empty string "". And anything that is not a falsy value is a truthy value.
Since [0] is not a falsy value, it is a truthy value, the if
statement evaluates to true & executes the statement.
2nd Example
var a = [0];
a == a // true
a == !a // also true, WTF?
Again type casting the values to primitive,
a = a
or [0].valueOf().toString() == [0].valueOf().toString()
or "0" == "0" // true; same type, same value
a == !a
or [0].valueOf().toString() == [0].valueOf().toString()
or "0" == !"0"
or "0" == false
or Number("0") == Number(false)
or 0 = 0 // true
참고URL : https://stackoverflow.com/questions/1724255/why-does-2-2-in-javascript
'Programing' 카테고리의 다른 글
Node.js 단위 테스팅 (0) | 2020.06.01 |
---|---|
Attributes.IsDefined ()에 과부하가없는 이유는 무엇입니까? (0) | 2020.06.01 |
빌드 유형이 제품 맛과 다른 이유는 무엇입니까? (0) | 2020.06.01 |
Python 3에서 x ** 4.0이 x ** 4보다 빠른 이유는 무엇입니까? (0) | 2020.06.01 |
WAR에서 주석을 사용하여 서블릿 필터 실행 순서를 정의하는 방법 (0) | 2020.06.01 |