执行上下文
概念
在 js 中代码执行需要一个环境,这个环境就是执行上下文。js 还有一个执行上下文栈(一种先进后出的数据结构),用来执行执行上下文。
执行上下文又分为全局执行上下文和函数执行上下文和eval执行上下文(不讲)
词法环境
一种存储变量,函数,作用域链的数据结构,允许访问外部变量和函数,执行完毕后被销毁
先上图:
在 ES6 中,词法环境和变量环境的区别在于前者用于存储函数声明和变量( let 和 const )绑定,而后者仅用于存储变量( var )绑定
执行上下文里面包含着词法环境,词法环境里面又包含环境记录器和外部环境的引用
环境记录器里面又包含声明式环境记录或对象环境记录
变量环境
它同样是一个词法环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。
如上所述,变量环境也是一个词法环境,所以它有着上面定义的词法环境的所有属性。
词法环境组件和变量环境的一个不同就是前者被用来存储函数声明和变量(let 和 const)绑定,而后者只用来存储 var 变量绑定。
全局执行上下文
全局执行上下文是在 js 代码执行前创建的,所以它是最先入栈,最后出栈的。
全局代码执行前,会在 堆内存中创建一个全局对象:Global Object (GO)【浏览器中是 window ,node 中是 global】
全局执行上下文中变量环境的对象环境记录上的属性会挂载到GO(全局对象)
全局执行上下文中,外部函数的引用为null(空对象)
函数执行上下文
函数执行上下文 会在函数执行时进入执行上下文栈,函数执行上下文通过声明性环境记录保存变量
外部环境引用指向父级词法环境,上图:
this
在执行上下文中,this 关键字表示当前执行上下文所属的对象。它的值取决于函数的调用方式。以下是一些常见的情况:
- 全局执行上下文:在全局执行上下文中,
this的值通常是全局对象(例如浏览器环境中的window对象)。
-
函数执行上下文:在函数执行上下文中,
this的值取决于函数的调用方式。有以下几种情况:- 函数作为普通函数调用:当函数作为普通函数调用时,
this的值通常是全局对象(非严格模式下)或undefined(严格模式下)。 - 函数作为对象方法调用:当函数作为对象的方法调用时,
this的值是调用该方法的对象。 - 函数作为构造函数调用:当函数作为构造函数调用时,
this的值是新创建的对象。 - 使用
call、apply或bind方法调用函数:通过这些方法调用函数时,可以显式地指定this的值。
- 函数作为普通函数调用:当函数作为普通函数调用时,
- 箭头函数执行上下文:在箭头函数执行上下文中,
this的值是在定义箭头函数时确定的,而不是在运行时确定的。它通常是包含箭头函数的最近的非箭头函数的this值。
需要注意的是,this 的值在运行时确定,而不是在定义时确定。它的值是动态的,取决于函数的调用方式。
作用域
作用域是可访问的变量,对象,函数的结合,同时也决定了这些变量的可访问性
javascript 中分为全局作用域和函数作用域以及块级作用域
- 全局作用域在页面打开时创建,页面关闭时销毁
- 函数作用域是在函数内创建的作用域,函数执行完毕,局部作用域会销毁
- 块级作用域与函数作用域类似,块级作用域里的变量只在当前块中有效,在块外无法访问。
var a = 20
function fn() {
var a = 10;
console.log(a);// 10
}
console.log(a);// 20
fn()
全局作用域会创建全局执行上下文,函数作用域会创建函数执行上下文,块级作用域会创建一个新的词法环境,不会创建执行上下文。
全局执行上下文和函数执行上下文我们前面已经详细的了解过了,块级作用域创建新的词法环境是怎么样的呢?