1
2
3
4
5
6
7
8
9
10
11
12
13
const secureBooking = functiong(){
let passengerCount = 0;

return funtion(){
passengerCount++;
console.log(`${passengerCount}`)
};
};

const booker = secureBooking();
booker();
booker();
booker();

![[Pasted image 20241114111853.png]]代码执行时

  • 首先在全局范围下有secureBooking变量,他的执行上下文(Execution Context)进入堆栈
  • 在seB函数范围下会有passengerCount的局部变量
  • 执行上下文也进入堆栈
  • 然后在```
    1
    const booker = secureBooking(); 
    的调用下,seB函数会返回一个函数,booker在全局范围内,所以它属于全局变量,而在调用完成后,seB的执行上下文会被弹出堆栈
  • 在调用
    1
    booker();
    时产生一个执行上下文,他范围内的变量为空,又因为他是在全区范围内
    ![[Pasted image 20241114113630.png]]
    但是他可以访问seB函数内的passerger是因为闭包
    ***一个函数总是可以访问创建他的执行上下文中的变量,即便他不存在于堆栈中
    闭包基本优先于作用域链

闭包定义

  • 一个函数总是可以访问创建他的执行上下文中的变量,即便该上下文不存在于堆栈中
  • 闭包使函数能访问所有在他的父函数中的变量
  • 闭包是值传递,而不是引用

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let f
(function () {

  const header = document.querySelector('h1');

  header.style.color = 'red';

  f = function () {

    document.body.addEventListener('click', function () {

      header.style.color = 'blue';

    });

  };

})();



f();
  • 全局的执行上下文加入堆栈,里面有f
  • 在函数执行时,函数的执行上下文加入堆栈,里面有header
  • 又因为闭包,导致f能访问到上面函数的header