深入理解JavaScript-作用域 VS 执行上下文


笔者在前文 作用域 、执行上下文 中介绍过作用域和执行上下文,它们是 JavaScript 中很重要的知识点,是基础中的重点,是重点中的基础。
我们讲过 JavaScript 中的作用域是词法作用域,与在哪里定义有关;而执行上下文则和调用有关,两者有关联但却是不同概念
作用域
作用域与哪里定义有关,在引擎编译时就知道它在哪里定义
其中函数作用域最为重要,因为作用域中的变量,作用域外不能访问,这起到了保护变量的作用
无生命周期
它可以理解为是“静态”的(词法作用域)
共全局作用域、函数作用域、块级作用域、eval 作用域
执行上下文
而执行上下文与调用有关
它表示一段代码执行时所带的所有信息
包括 this、词法环境、变量环境(ES5标准)
结合之前 this 所给的定义:谁调用它,this 就指向谁 就是和执行上下文相关。执行上下文也是如此,与调用者息息相关
生命周期为两个阶段
指向代码
确定作用域链
确定 this 指,即我们熟知的 this 绑定
创建变量环境
创建词法环境
指向父作用域(作用域在代码执行前就确定了)
登记 var、function 等声明的变量
此时会发生变量提升和函数提升
环境记录器
对外部环境的引用(outer)
同样指向父作用域
登记 let、const 等声明的变量
会发生变量提升(hoist),但是不会被初始化,所以提前使用会报 ReferenceError,如例1所示
环境记录器
对外部环境的引用(outer)
创建阶段
执行阶段
它则是“动态”的(与调用方相关)
共全局执行上下文、函数执行上下文、模块执行上下文、eval 执行上下文
例子1:
a // undefinedb // ReferenceErrorc // ReferenceErrord // function d() {}var a = 1;let b = 2;const c = 3;function d(){}
var 声明变量会被初始化为 undefined,一般函数(函数声明式写法)定义会被初始化为 function xx(){} ,let、const 则不会被初始化,所以 var 定义的变量可以提前使用但指为 undefined,一般函数定义可以正常提前使用,let、const 提前使用则会报错
PS,如果使用函数表达式写法使用函数,则跟变量,如 var e = function(){} 或者 let f = () => {}
以上就是作用域和指向上下文的各种区别
⚠️「随朱波流」只是记录本人关于编程、生活、个人成长、思考的自留地。如有需要,可前往 blog.azhubaby.com(阅读原文)中查看第一手文章
到顶部