[javascript] 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] 이후 가능합니다.


답변

다른 답변에 약간의 세부 사항을 추가하려면 …을 비교할 때 ArrayA를Number , 자바 스크립트가 변환됩니다 Array함께 parseFloat(array). 콘솔 (예 : Firebug 또는 Web Inspector)에서 직접 시도하여 다른 Array값으로 변환되는 것을 확인할 수 있습니다.

parseFloat([2]); // 2
parseFloat([2, 3]); // 2
parseFloat(['', 2]); // NaN

들면 ArrayS, parseFloat온 동작을 수행Array 최초 부재 파기 나머지.

편집 : Christoph의 세부 사항에 따르면 내부에서 더 긴 형식을 사용하고 있지만 결과는 일관되게 동일 parseFloat하므로 언제든지 사용할 수 있습니다parseFloat(array) 속기로 하여 변환 방법을 알 수 있습니다.