В глобальном окружении объявляется переменная a (window.a)
Объявление поднимается на самый верх - всплытие переменных
var a;
Самовызывающаяся функция
(function(){
a = 2;
(function(){
b = 3;
})();
})();
Интерпретатор ищет переменную а в лексическом окружении функции и не находит её
Далее он начинает искать её во внешнем объекте переменных. В данном случае - это window
Происходит присвоение window.a = 2
a = 2;
Тоже самое, что и с переменной а, только во внешнем объекте переменных тоже нет такой переменной и интерпретатор начинает искать её во внешнем объекте переменных первой функции, т.е. в глобальном окружении.
b = 3;
К слову, если бы не было присвоения переменных a=2 и b=3, то вывод этих переменных в консоль вывело undefined для a, а для b выбросило бы исключение, т.к. b не была объявлена.