예제

(![] + [])[+[]] // "f"
+
(![] + [])[+!+[]] // "a"
+
([![]] + [][[]])[+!+[] + [+[]]] // "i"
+
(![] + [])[!+[] + !+[]]; // "l"

// "fail"

풀이

(false + '')[0]
+
(false + '')[1]
+
(['false'] + undefined)[1 + [0]] -> 'falseundefined'['10']
+
(false + '')[true + true] -> ('false')[1 + 1] -> ('false')[2]

다른 예제

// #1
5 - "1" // 4
// 해설: (-) 연산자의 경우 숫자로만 적용될 수 있으므로 강제 형변환이 되어 연산된다.

// #2
5 + "1" // "51"
// 해설: (+) 연산자의 경우 문자열과의 연산이 존재하면 문자열로 트리거 되어 합해서 반환된다.

// #3
[] + {} // "[object Object]"
// 해설: []의 경우 빈 배열에서 빈문자열 ''을 반환하고, '' + {} 처럼 문자열 연산이기 때문에
// {}도 문자열로 변환되어 더해진다.
// {}의 경우 문자열로 변환하면 빈 객체를 반환하겠지만 "[object Object]"를 반환한다.

// #4
{} + [] // 0
// 해설: {} 인 빈 객체의 경우 빈 객체를 빈 객체로 간주되지 않고 빈 코드 블록으로 간주된다.
// { nothing here } + [] 와 같은 의미이다.

// #5
+[] // 0
// 해설: []의 경우 빈 배열에서 빈 문자열 ''로 변환되고, + 연산자로 인해 숫자로 변환되며
// ''를 숫자로 변환하면 0이 된다.

// #6
![] // false
// 해설: 빈 객체든 어떤 객체든 논리연산자 !(Not)을 통해 false로 변환된다.

// #7
!![] // true

// #8
'hello'[1] // 'e'

가능한 TypeScript 쓰자…