为了更好的学习和使用javascript,我们需要理解作用域链与闭包。
作用域
在javascript中,作用域可以看作是一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符(变量名或者函数名)名称进行变量查找
js的执行 包括编译阶段和执行阶段,编译阶段由编译器完成,将代码翻译成可执行的代码,这个阶段作用域会确定。执行阶由引擎完成,段会利用 v8 等浏览器引擎执行,执行上下文在这个阶段完成。
编译阶段
- 词法分析
- 语法分析
- 可执行代码生成
- 作用域规则确定
执行阶段
- 执行上下文创建
- 代码执行
- 垃圾回收
执行上下文生命周期
创建阶段
- 生成变量对象
- 建立作用域
- 确定this指向
执行阶段
- 变量赋值
- 函数引用
- 执行其他代码
为什么创建作用域是在编译阶段,而创建作用域链是在执行阶段呢?
作用域与作用域链是两个不同的概念。
作用域是一套规则。
作用域链是这套规则的实现,它是由当前环境与上层环境的一系列变量和对象组成,它保证了当前执行环境对符合访问权的变量和函数的有序访问。
闭包
如果一个函数可以记住并访问所在的作用域(全局作用域除外),并在定义该函数作用域之外执行时 ,该函数可以称之为闭包。
javascript拥有垃圾自动回收机制。其中一个重要的概念是,当一个值在内存中失去引用的时候,垃圾回收机制将会根据特殊的算法找到它,并回收掉,释放内存。
正常函数的执行上下文,执行完毕后,生命周期结束,该函数的执行上下文失去引用,很快会被垃圾回收并释放内存。而闭包的存在,会阻止这个过程。
通过闭包我们可以访问到函数内部的变量,这是闭包的一个特性。
应用场景:
- 延时设置setTimeout
- 回调函数
- 柯里化
- 模块