阅读 128

执行上下文与作用域

变量提升与函数提升

变量声明提升:通过var定义(声明)的变量,在定义语句之前就可以访问到,值为undefined;

函数声明提升:通过function声明的函数,在之前就可以直接调用

注意:必须是function声明的函数

var myfun = function (){
  
}  //不能提前调用,算作变量提升
复制代码

先执行变量提升,再执行函数提升

记住一句话:函数提升优先级高于变量提升,且不会被同名变量声明覆盖,但是会被变量赋值后覆盖

varfunction声明的变量创建在全局对象中,而let`const\class`声明的变量创建在全局scope当中

查找变量的时候,会先到scope中找变量,查找不到再到全局对象中查找

执行上下文

JavaScript 在执行语句之前,经过一系列的“准备”,为代码执行创造一个“教室”——执行上下文

代码分类(根据位置来分)

  1. 全局代码
  2. 函数代码 也叫局部代码

全局执行上下文

在执行全局代码前将window确定为全局执行上下文

对全局数据进行处理

1. `var`定义的全局变量, ==> undefined ,添加为window的属性
2. function声明的全局函数  ==>赋值(fun),添加为window的方法
3. this ==>赋值(window)
复制代码

开始执行全局代码

函数执行上下文

调用函数,准备执行函数体之前,创建函数执行上下文对象,在调用的时候产生函数执行上下文,函数调用结束后就会自动释放。

对局部数据进行预处理

1. 形参变量 ==> 赋值(实参) ==> 添加为执行上下文的属性
2. arguments ==>赋值(实参列表) ,添加为执行上下文的属性
3. `var`定义的全局变量, ==> undefined ,添加为执行上下文的属性
4. function声明的全局函数  ==>赋值(fun),添加为执行上下文的方法
5. this ==>赋值(调用函数的对象)
复制代码

开始执行函数体代码

执行上下文栈

执行上下文的个数=N(调用函数的个数)+1(window)

在全局代码执行前,JS引擎会创建一个栈来管理所有产生的执行上下文对象

<script>
  
  var a = 10;
  var bar = function(x){
    var b = 5;
    foo(x + b);
  }
  var foo = function(y){
    var c = 5;
    console.log(a + c + y)
  }
  bar(10)''
</script>
复制代码

如图所示:当前运行的总是栈顶的

lalal01.png

执行栈栈顶的执行上下文称为当前执行上下文

JS代码总在当前执行上下文中运行

4种情况会创建新的执行上下文:

  1. 进入全局代码
  2. 进入function函数体代码
  3. 进入eval函数参数代码
  4. 进入module代码

作用域

它就是一块儿地盘,显示一个代码所在的区域,与执行上下文不同,它是静态的,在我们编写代码的时候就已经确定了。作用是隔离变量,不同作用域下同名变量不会有冲突。

全局作用域

函数作用域

块作用域(ES6之后)

作用域的个数=N(声明函数的个数)+1(window)

作用域链

多个上下级关系的作用域形成的链,它的方向是从下到上的(从内到外),查找变量的时候,沿着作用域链来找

变量的查找规则:

在当前作用域下的执行上下文中查找对应的属性,如果有就直接返回,否则进入上一级作用域的执行上下文中查找对应的属性,若没有,就一直向上查找,直到全局作用域链,若出现了还找不到的情况,就抛出异常。

\

文章分类
前端
文章标签