Programing

JavaScript에서 왜 2 == [2]입니까?

lottogame 2020. 6. 1. 07:41
반응형

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 Arrays, 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

반응형