Сделать переменные, как глобальные переменные - PullRequest
0 голосов
/ 12 января 2020

Мне интересно, возможно ли переместить набор переменных из глобальной области во вложенную область. Можно ли использовать замыкание для достижения этого в следующем контексте? Должно быть, верно?

Переменные let, вероятно, не должны попадать в область действия renderInfo(), потому что renderInfo() вызывается несколько раз при загрузке, и этого нельзя избежать. Каждый раз, когда вызывается renderInfo(), render() визуализирует несколько элементов, к каждому из которых добавлен прослушиватель событий click. Следовательно, переменные также не могут быть здесь с тем, как код в настоящее время структурирован.

Я пытался превратить clickToSort() в замыкание, но я сталкиваюсь с проблемами каждый раз. Я не могу понять, как разрешить всем элементам с прослушивателем событий click share доступ к let переменным.

let
  sortNameAscending =
  sortFreeAscending =
  sortSizeAscending = true

// Called multiple times at load.
function renderInfo(a,b,c,d) {

  // Renders multiple elements, and adds an event listener to them, each call.
  function render(){
    // The event listener is added to multiple elements
    // that are also rendered herein.
    ele.addEventListener('click', (e)=>clickToSort(e, cls, 'aString'))
  }

  // This function is added to the click event of tons of elements.
  function clickToSort(e, cls, dataProperty) {

    // How do I move the let variables from the global
    // scope to here, so that they behave as if they
    // are in the global scope? Is it possible with a
    // closure?
    // let
    //  sortNameAscending =
    //  sortFreeAscending =
    //  sortSizeAscending = true

    // I imagine the following code should be wrapped in
    // its own scope, but the scope must have access to
    // the arguments of clickToSort(), and the let variables
    // which should behave as if they are global.
    if (cls.includes('whatever')) {
      sortNameAscending = !sortNameAscending
    } else if (cls.includes('whatever2')) {
      sortFreeAscending = !sortFreeAscending
    } else {
      sortSizeAscending = !sortSizeAscending
    }
  }
}

Я попробовал следующее, но это не сработало.

let
  sortNameAscending =
  sortFreeAscending =
  sortSizeAscending = true

function renderInfo(a,b,c,d) {

  function render(){
    // The event listener is added to multiple elements
    // that are also rendered herein.
    ele.addEventListener('click', (e)=>clickToSort(e, cls, 'aString'))
  }

  function clickToSort(e, cls, dataProperty) {

    let
      sortNameAscending =
      sortFreeAscending =
      sortSizeAscending = true

    ;(function whatevs(){
      if (cls.includes('whatever')) {
        sortNameAscending = !sortNameAscending
      } else if (cls.includes('whatever2')) {
        sortFreeAscending = !sortFreeAscending
      } else {
        sortSizeAscending = !sortSizeAscending
      }
    )()
  }
}

Я не уверен почему, хотя это, вероятно, связано с тем фактом, что я связал clickToSort() функция для элементов, вместо того, чтобы возвращать функцию?

1 Ответ

1 голос
/ 12 января 2020

Вы можете заключить всю функцию в немедленно вызванное выражение функции . Это обеспечит закрытие трех ваших переменных и позволит вашим вызовам использовать одни и те же данные.

В вашей анонимной функции вы можете объявить вложенные переменные и вернуть функцию, которая изначально называлась renderInfo. Когда ваш код будет выполнен, эти три переменные будут объявлены и сохранены в области действия анонимной функции, тогда renderInfo будет присвоено значение функции.

// Called multiple times at load.
const renderInfo = (function() {

  let
    sortNameAscending =
    sortFreeAscending =
    sortSizeAscending = true

  return function(a, b, c, d) {

    // Renders multiple elements, and adds an event listener to them, each call.
    function render() {
      // The event listener is added to multiple elements
      // that are also rendered herein.
      ele.addEventListener('click', (e) => clickToSort(e, cls, 'aString'))
    }

    // This function is added to the click event of tons of elements.
    function clickToSort(e, cls, dataProperty) {

      if (cls.includes('whatever')) {
        sortNameAscending = !sortNameAscending
      } else if (cls.includes('whatever2')) {
        sortFreeAscending = !sortFreeAscending
      } else {
        sortSizeAscending = !sortSizeAscending
      }
    }

  }

})()

Простой пример использования IIFE ( выражения немедленного вызова функции ) для создания замыкания следующий:

const add = (function() {
  let sum = 0;
  return function() {
    return ++sum;
  }
})()

console.log(add())
console.log(add())
console.log(add())
console.log(add())
...