Закрытие понимания с помощью стека вызовов - PullRequest
0 голосов
/ 11 апреля 2020

Я пытаюсь понять javascript замыкание относительно стека вызовов в javascript.

Я столкнулся с примером замыкания, которое

function a() {
  let grandpa = 'grandpa'
  return function b() {
    let father = 'father'
    return function c() {
      let son = 'son'
      return `${grandpa} > ${father} > ${son}`
    }
  }
}

let x = a();
let y = x();
y();

Теперь согласно моим Понимание стека вызовов: когда мы вызываем функцию a (), она помещается в стек, а затем, когда мы запускаем функцию 'b', она перемещается над 'a', а затем функция 'c' над 'b'. Поэтому, по моему мнению, это должно выглядеть примерно так:

enter image description here

Однако объяснение, которое я наткнулся на этот пример, показывает, что замыкание говорит о том, что: -

"Когда мы вызывали функцию 'a', то, что мы имели в ответ, было функцией 'b', после возврата 'b', функция 'a' выскочила из стека, поэтому ее переменная среда была удалена (концепция сборка мусора - алгоритм разметки и очистки). Но, тем не менее, функция 'c' имеет доступ к переменным 'grandpa' и 'Father' '

Насколько я понимаю, JS стек вызовов следует за Концепция первого в последнем из (или, скажем, последний в первом из). Таким образом, если стек вызовов следует за LIFO, то почему a () выталкивается из стека до c (), разве сначала не должно выталкиваться c (), затем b () и затем a () ??

Мне кажется, что объяснение закрытия здесь противоречит пониманию моего стека вызовов.

Буду признателен, если кто-нибудь сможет объяснить этот пример закрытия вместе со стеком вызовов?

1 Ответ

0 голосов
/ 11 апреля 2020

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

Закрытие - это просто объект, который имеет только переменные, используемые после окончания выполнения функции, и область его действия находится внутри дочерней функции, которая продолжала использовать эти переменные

Вот пример использования :

// makes an interface of an array
function cArr() {
  var x = {a: []};
  function a(n) {
    if(n) {
      x.a.push(n);
    }
  }
  function b() {
    console.log(x);
  }
  return {
    add: a,
    print: b
  }
}

var y = cArr();
y.print();
// []
y.add("Tom");
y.print();
// ["Tom"]
y.add() // without an argument but he have handled that :)
y.print();
// ["Tom"]

и этот массив нельзя изменить, только добавив в него элементы, это пример силы замыканий

...