作用域是什么?
了解作用域之前,我们得先弄清楚以下几个概念
-
变量和函数的声明函数的生命周期
-
函数的生命周期
-
Activetion Object(AO)、Variable Object(VO)
变量提升和函数声明
变量提升
变量提升:在JavaScript引擎解析JavaScript代码的时候,首先,JavaScript引擎会把变量和函数的声明提前进行预解析,然后再去执行其他代码。
变量声明:变量的声明只有一种方式,那就是用var关键字声明,用let和const关键词声明得不会有变量提升。直接赋值不是一种声明方式。这仅仅是在全局对象上创建了新的属性(而不是变量)。它们有一些区别:
1)赋值并不会提升,如下表
函数声明
函数得声明有三种方式 1)function fn ){ }直接创建方式
function fn(){
}
复制代码
2)new Funtion构建函数创建
var fn = new Function('a','b', 'return a+b')
复制代码
等价于如下式
function fn(a,b){
return a+b
}
复制代码
3)给变量赋值匿名函数方法创建
var fn = function(a,b){
}
复制代码
上面的三种方式,后面两种方法,在声明前访问时,返回的都是一个undefined的变量。当然,在声明后访问它们都是一个function的函数。
注意:如果变量名和函数名声明时相同,函数优先声明。
函数的生命周期
函数的的生命周期分为创建和执行两个阶段。
在函数创建阶段,JS解析引擎进行预解析,会将函数声明提前,同时将该函数放到全局作用域中或当前函数的上一级函数的局部作用域中。
在函数执行阶段,JS引擎会将当前函数的局部变量和内部函数进行声明提前,然后再执行业务代码,当函数执行完退出时,释放该函数的执行上下文,并注销该函数的局部变量。
什么是AO和VO
英文解释: AO:Activetion Object(活动对象) VO:Variable Object(变量对象)
1、VO对应的是函数创建阶段,JS解析引擎进行预解析时,所有的变量和函数的声明,统称为Variable Object。该变量与执行上下文相关,知道自己的数据存储在哪里,并且知道如何访问。VO是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:
- 变量 (var, 变量声明);
- 函数声明 (FunctionDeclaration, 缩写为FD);
- 函数的形参
举个例子
- 函数的所有局部变量
- 函数的所有命名参数
- 函数的参数集合
- 函数的this指向
举个例子:
作用域链
在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程,从第一个对象开始,逐级向后回溯,直到找到同名标识符为止,找到后不再继续遍历,找不到就报错。它是变量的一种查找机制 例如: