Q:

Как работает код счётчика, в котором одна функция возвращает другую функцию?

function makeCounter() {
  var currentCount = 1;

  // возвращаемся к функции
  return function counter() {
    return currentCount++;
  }
};
var d = makeCounter()

В внутри функции makeCounter мы создаем функция counter в которой увеличиваем значение currentCount на 1 т.к так переменная currentCount не объявлена она ищет ее с помощью скрытого свойства [[scope]] которое есть у функции; переменная currentCount = 1; ее и увеличивает функция counter т.к. внутри функции переменная currentCount++  с постинкрементом  то значение увеличивается но возвращается старое значение. переменная d = 1; 
 а что происходит в этом коде ?

function makeCounter() {
  var currentCount = 1;

  // возвращаемся к функции
  function counter() {
    return currentCount++;
  }

  // ...и добавляем ей методы!
  counter.set = function(value) {
    currentCount = value;
  };

  counter.reset = function() {
    currentCount = 1;
  };

  return counter;
}

var counter = makeCounter();

тут возвращается не функция а что ? не могу понять 

A:

Функция makeCounter - это конструктор счётчика. Вызывая ее будет возвращен новый объект счетчика. Здесь это видно
function makeCounter() {
    ...
    return counter;
}

var counter = makeCounter();

Сам возвращаемый counter, если посмотреть чуть выше, является функцией
function counter() {
    return currentCount++;
}

Иными словами, вызывая makeCounter() (создать счетчик) мы просто получаем на выходе другую функцию - counter (которая уже является самим счетчиком). Эту функцию теперь можно вызывать и при этом благодаря такой замечательной штуке как "замыкания" будет возвращена и инкрементирована локальная (локальная для makeCounter) переменная currentCount, содержащая текущее значение счетчика. Вызываем counter 1 раз - выход 1. Вызываем десять подряд - последним значением получим 10. Ничего сложного здесь

function makeCounter() {
  var currentCount = 1;

  function counter() {
    return currentCount++;
  }

  return counter;
}

var counter = makeCounter();
console.log(counter());
counter()
counter()
counter()
counter()
counter()
counter()
counter()
counter()
console.log(counter());

Интереснее с вот этой частью
  counter.set = function(value) {
    currentCount = value;
  };

  counter.reset = function() {
    currentCount = 1;
  };

На самом деле ничего сложного здесь тоже нет. Стоит помнить что в JavaScript практически все является объектом. Функции в том числе. Поэтому равно как вы можете добавлять свойства объекту (var o = {}; o.a = 1; o.b = 2;), точно так же вы можете добавлять свойства и функции. Так почему бы не добавить нашему счетчику возможность начинать счет с чего-нибудь кроме единицы? Или сбрасываться в начальное состояние?
Так и сделано. Добавлены свойства (точнее сказать методы) объекту counter (да-да, именно объекту, ведь какая разница, что это функция?) с названиями set и reset, которые, соответственно, устанавливают счетчик в какое-нибудь значение, указанное Вами, или обнуляют (точнее "объединичивают") счетчик

function makeCounter() {
  var currentCount = 1;

  function counter() {
    return currentCount++;
  }

  counter.set = function(value) {
    currentCount = value;
  };

  counter.reset = function() {
    currentCount = 1;
  };

  return counter;
}

var counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3

counter.reset(); // обнуляем, снова будет 1

counter(); // 1
counter(); // 2
counter(); // 3

counter.set(10); // а теперь возьмем и установим счетчик в 10

counter(); // 10
counter(); // 11
counter(); // 12

// Проверяем?
console.log(counter()); // должно быть 13

