执行上下文
1.什么是“执行上下文”
通俗的定义就是:在执行代码之前,把将要用到的所有的变量都事先拿出来,有的直接赋值了,有的先用undefined占个空。
执行上下文可以简单理解为一个对象:
它包含三个部分:
- 变量对象(VO)
- 作用域链(词法作用域)
this
指向
类型:
- 全局执行上下文
- 函数执行上下文
eval
执行上下文
代码执行过程:
- 创建 全局上下文 (global EC)
- 全局执行上下文 (caller) 逐行 自上而下 执行。遇到函数时,函数执行上下文 (callee) 被
push
到执行栈顶层 - 函数执行上下文被激活,成为 active EC, 开始执行函数中的代码,caller 被挂起
函数执行完后,callee 被
pop
移除出执行栈,控制权交还全局上下文 (caller),继续执行
2.示例
先来看几段代码
console.log(a)
console.log(a)
var a
console.log(a)
var a = 1
第三断代码输出的是undefined,说明浏览器在执行console.log(a)时,已经知道了a是undefined,但是却不知道它是10。3.变量提升
我们要了解一下什么是变量提升
先来看一段代码console.log(a) //undefined
var a = 100
fn('zhangsan') //'zhangsan' 20
function fn(name){
age = 20
console.log(name,age)
var age;
}
当我们看到这段代码的执行结果时是否会产生一个疑惑?为何函数先执行,后定义时一样可以正确的调用函数。
在解析代码之前我们先了解一下变量提升的概念。变量提升
在使用
javascript
编写代码的时候, 我们知道, 声明一个变量用var
, 定义一个函数用function
.那你知道程序在运行它的时候, 都经历了什么吗?变量声明提升
首先是用
var
定义一个变量的时候, 例如:var a = 10;
大部分的编程语言都是先声明变量再使用, 但是
javascript
有所不同, 上面的代码, 实际相当于这样执行:var a;
a = 10;
因此有了下面这段代码的执行结果:
console.log(a); // 声明,先给一个默认值undefined;
var a = 10; // 赋值,对变量a赋值了10
console.log(a); // 10
这就是最简单的变量声明提升.
典型题 ```javascript function foo() {console.log(‘foo1’);
}
foo(); // foo2
function foo() {
console.log('foo2');
}
foo(); // foo2
打印的结果是两个 `foo2`
```javascript
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
小结
- JavaScript 代码执行过程中,需要先做变量提升,而之所以需要实现变量提升,是因为 JavaScript 代码在执行之前需要先编译。
- 在编译阶段,变量和函数会被存放到变量环境中,变量的默认值会被设置为 undefined;在代码执行阶段,JavaScript 引擎会从变量环境中去查找自定义的变量和函数。
- 如果在编译阶段,存在两个相同的函数,那么最终存放在变量环境中的是最后定义的那个,这是因为后定义的会覆盖掉之前定义的。