"NaNundefined"[10] ="e" is easy - e is the eleventh char in the string.
([+[][[]]]+[][[]])[++[[]][+[]]+[+[]]] = "e" is a bit harder, but you can easily just split it up:
[+[][[]]] -> [ NaN ]
[][[]] -> undefined
[ NaN ] + undefined -> "NaNundefined"
++[[]][+[]] -> 1
[+[]] -> "0"
1 + "0" -> "10"
"NaNundefined"["10"] -> "e"
The second version is effectively a way to construct the first, (ab)using the weak typing of javascript operators (for example, [NaN] + "" -> "NaN"). It also uses the fact that arrays in javascript are always indexed by a string (so array[10] is equivalent to array["10"]).
The second version could be seen as a obfuscation, if you want to prevent someone to understand the code. It doesn't really serve much of a purpose though, at least in everyday coding life.