js的作用域&作用域链,闭包

111 阅读3分钟

1. 作用域:

Scope,变量(变量作⽤域݈又称为上下⽂)和函数存在的范围,内层作⽤域可以访问外层作⽤域的变量,反之不⾏.

js是词法作用域:⼜叫做静态作⽤域,变量被创建时就确定好了,⽽不是执⾏阶段。

  • 全局作用域:

在代码任何地⽅都能访问到的对象拥有全局作⽤域. ⼀般以下⼏种情形有全局作⽤域链:

  1. 最外层函数和在最外层函数外⾯定义的变量拥有全局作⽤域
  2. 所有末定义直接赋值的变量⾃动声明为拥有全局作⽤域
  3. 所有window对象的属性拥有全局作⽤域
  • 函数作⽤域:是指声明在函数内部的变量,和全局作⽤域相反,局部作⽤域⼀般只在固定的代 码⽚段内可访问到
  • 块级作⽤域(ES6新增)

块级作⽤域可通过新增命令let和const声明,所声明的变量在指定块的作⽤域外⽆法被访问。 块级作⽤域在如下情况被创建:

  1. 在⼀个函数内部
  2. 在⼀个代码块(由⼀对花括号包裹)内部

特点: 声明变量不会提升到代码块顶部 禁⽌重复声明 循环中的绑定块作⽤域的妙

for循环还有⼀个特别之处,就是设置循环变量的那部分是⼀个⽗作⽤域,⽽循环体内部是⼀ 个单独的⼦作⽤域。

2. 作⽤域链

当查找变量时,会先从当前上下⽂的变量对象中查找,从当前作⽤域开始⼀层层往上找某个变量, 如果没有找到,就会从⽗级(词法层⾯上的⽗级执⾏上下⽂的变量对象中查找,⼀直找到全局 上下⽂的变量对象,(多个执⾏上下⽂的变量对象构成的链表叫做作⽤域链)

说人话:当前作⽤域范围(⾃身内部)中找不到时,就会往他的上⼀级找,直到全局没有 的,反回 undefined̶

块语句(⼤括号{}中间的语句),如 if 和 switch 条件语句或 for 和 while 循环语句,不是函数,不会创建⼀个新的作⽤域。

  • 先从本层看有没有var

3.闭包

  • 闭包:是指那些能够访问⾃由变量的函数.

  • ⾃由变量:是指在函数中使⽤的,但既不是函数参数也 不是函数的局部变量的变量。

  • 闭包 = 函数 + 函数能够访问的⾃由变量。

闭包的变量存在堆中,即解释了函数调⽤之后为什么闭包还能引⽤到函数内的变量。

闭包的形成需要两个条件:
  • 闭包是在函数被调⽤执⾏的时候才被确认创建的。

  • 闭包的形成,与作⽤域链的访问顺序有直接关系。

  • 只有内部函数访问了上层作⽤域链中的变量对象时,才会形成闭包,因此,我们可以利⽤闭包来访问函数内部的变量。

  • 闭包,本质上是上级作⽤域内变量的⽣命周期,因为被下级作⽤域引⽤,没有得到释放,需要等到下级作⽤域执⾏完后才得到释放。

  • 作⽤

  1. 独⽴作⽤域,避免变量污染
  2. 实现缓存计算结果
  3. 库的封装 jQuery
  • 运⽤

1.防抖节流

+ 防抖:事件触发⾼频到最后⼀次操作,如果规定时间内再次触发,则重新计时。

image.png

  1. 模拟块级作⽤域

image.png