шаг str2 = str2 + str[str.length]; - лишний, так как с него начинается, то NaN появляется впереди
http://es5.javascript.ru/x11.html#x11.6.1
пункт 7 не срабатывает, так как типы обоих операндов не String,
следовательно срабатывает пункт 8 в попытке привести аргументы к числу,
undefined приводится к NaN (
http://es5.javascript.ru/x9.html#x9.3), str2 на первом шаге undefined, также как и str2[str.length]
если хотя бы один аргумент NaN - результат NaN (
http://es5.javascript.ru/x9.html#x9.3),
вот он ваш NaN, если бы str2 была объявлена как var str2 = ''; то вначале получили бы не NaN, а undefined
PS: если где-то выскакивает что-то непонятное, как в данном примере, смотрите в
спецификации алгоритмы работы, после этого, если что не понятно, спрашивайте
UPD: пока писал
oneguy подключился