alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);
이 코드의 출력은 다음과 같습니다 fail
.. 왜?
그건 그렇고, (![]+[])[+!+[]] == 'false'[1]
맞죠?. 하지만 왜 ![]+[] == "false"
그리고 왜 +!+[] == 1
?
답변
@Mauricio가 언급했듯이 (![]+[])[+[]]
“f”( “false”의 첫 번째 문자), (![]+[])[+!+[]])
“a”등입니다.
어떻게 작동합니까?
첫 번째 문자 ‘f’를 살펴 보겠습니다.
(![]+[])[+[]]; // 'f'
표현식의 첫 번째 부분 (괄호 사이 ) 은로 구성되며 ![]+[]
, 더하기 연산자의 첫 번째 피연산자는 ![]
이며 이는 false
다른 Object 인스턴스와 마찬가지로 배열 객체가 진실 이고 논리 (!) NOT 단항을 적용하기 때문입니다. false
예를 들어 값을 생성합니다 .
![]; // false, it was truthy
!{}; // false, it was truthy
!0; // true, it was falsey
!NaN; // true, it was falsey
그 다음에는 빈 배열의 두 번째 피연산자 인 빈 배열이 있습니다. 빈 배열의 문자열 표현이 빈 문자열이기 때문에 값을 문자열 []
로 변환하기 위해 만들어집니다 false
.
false+[]; // "false"
false+''; // "false"
마지막 부분 인 괄호 뒤의 대괄호 쌍은 속성 접근 자이며 빈 배열에 다시 적용된 단항 더하기 연산자로 구성된 식을받습니다.
단항 더하기 연산자가하는 일은 다음과 같은 형식 변환입니다 Number
.
typeof +"20"; // "number"
한 번 더, 이것은 빈 배열에 적용되며, 앞서 말했듯이 배열의 문자열 표현은 빈 문자열이며 빈 문자열을 숫자로 변환하면 0으로 변환됩니다.
+[]; // 0, because
+[].toString(); // 0, because
+""; // 0
따라서 몇 단계에서 표현식을 “디코딩”할 수 있습니다.
(![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0]; // "f"
문자열 값에 대괄호 표기법을 사용하여 문자에 액세스하는 것은 ECMAScript 3rd의 일부가 아닙니다. 에디션 사양 (이것이 charAt
방법이 존재하는 이유입니다 ).
그러나 문자열의 문자를 나타내는 이러한 종류의 “인덱스 속성”은 ECMAScript 5에서 표준화되었으며 표준화 이전에도 많은 브라우저에서이 기능을 사용할 수있었습니다 (IE8 (표준 모드)에서도 가능).