Как сделать независимые счетчики?

У меня непонятная ситуация, что не так со счетчиком ? При клике на разные кнопки в них выводится ранее выставленное значение. Вместо того, чтобы начинать отсчет заново для каждой кнопки.

let likes = document.querySelectorAll('.btn-like');

let buttonClik = function(evt) {
  let currentLike = evt.currentTarget;
  currentLike.textContent = doCount();
}

let getLike = function() {
  let likeCount = 0;

  let counter = function() {
    return likeCount += 1;
  }

  return counter;
}

let doCount = getLike();

for (let elem of likes) {
  elem.addEventListener('click', buttonClik);
}
<body>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
</body>


Ответы (2 шт):

Автор решения: Yugofx

У вас likeCount находится в замыкании. Поэтому когда вы вызываете doCount, вы меняете одну и ту же переменную. Чтобы заставить ваш вариант работать, вам нужно проинициализировать getLike для каждой кнопки.

let likes = document.querySelectorAll('.btn-like');

let createButtonClickHandler = function() {
  const counterFn = getLike();
  return function(evt) {
      evt.currentTarget.textContent = counterFn();
  }
}

let getLike = function() {
  let likeCount = 0;

  const counter = function() {
    return ++likeCount;
  }

  return counter;
}

for (let elem of likes) {
  elem.addEventListener('click', createButtonClickHandler());
}
→ Ссылка
Автор решения: Денис Степанов

@Yugofx уже ответил на ваш вопрос, я лишь добавлю, что вы можете использовать параметры по умолчанию внешних функций для создания замыканий.

Иногда это может упростить запись.

let likes = document.querySelectorAll('.btn-like');

let count = (i = 0) => e => e.currentTarget.innerText = ++i;

likes.forEach(like =>
  like.addEventListener('click', count())
);
<body>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
  <button class="btn btn-like">+</button>
</body>

→ Ссылка