最后更新时间:2023-06-02 13-59-20
代码段
// 全局代码
<script type="text/javascript">// 代码段...</script>;
// eval代码接收的也是一段文本形式的代码
eval("alert(123)");
// 函数体是代码是因为函数在创建时,本质上是new Function(...)得来的,其中需要传入一个文本形式的参数作为函数体
function fn(x) {
console.log(x + 5);
}
执行上下文
在一段 JS 代码执行之前,浏览器会做一些准备工作
- 对代码段中的 变量,函数表达式进行声明, 而不是赋值,变量赋值 是在赋值语句执行的时候进行的
- 对代码段中的 this 进行赋值
- 对代码段中的函数声明 进行赋值
如果代码段是函数体情况
- 对 arguments 变量进行赋值
- 对自由变量进行赋值,并确定取值作用域
执行上下文环境
在代码执行之前,将要用到的所有变量都事先拿出来,有的直接赋值,有的先用 undefined 占个空
- 函数每被调用一次,都会产生一个新的执行上下文环境.(因为不同的调用可能会有不同的参数)
- 函数在定义的时候(不是调用的时候),就已经确定了函数体内部自由变量的作用域
执行上下文栈
- 执行全局代码时,会产生一个执行上下文环境
- 每次调用函数都又会产生执行上下文环境
- 当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境
- 处于活动状态的执行上下文环境永远只有一个
- 其实这是一个压栈出栈的过程--执行上下文栈
作用域
最大的用处就是隔离变量,不同作用域下同名变量不会有冲突
- JavaScript 除了全局作用域之外,只有函数可以创建的作用域
- 一段代码中,每一个函数都会形成一个作用域
- 作用域有上下级的关系,上下级关系的确定就看函数在那个作用域下创建的
- 作用域只是一个底盘,一个抽象的概念,其中没有变量,要通过作用域对应的执行上下文环境获取变量的值,同一个作用域下,不同的调用会产生不同的执行上下文环境,继而产生不同的变量的值。
- 所有,作用域中变量的值是在执行过程中产生确定的,但是作用域是在函数创建时就确定了。
- 所以,如果要查找一个作用域下某个变量的值,就需要找到这个作用域对应的执行上下文环境,再到其中寻找变量的值
作用域链
沿着作用域上下级寻找,我们称之为作用域链
自由变量
- 在 A 作用域中使用过了变量 X,但是却没有在 A 作用域中声明,对于 A 作用域来说,X 就是一个自由变量
- 寻找自由变量的值,要到创建这个函数的作用域取值(是创建),而不是(调用)----这就是所谓的"静态作用域"
this 指向问题
- 构造函数中的 this,this 指向构造函数创建出来的对象
- 函数作为一个对象的属性,并且作为对象的一个属性被调用时,函数中的 this 指向该对象
- 函数用 call 或者 apply 调用时,this 的值就取传入的对象的值。
- 全局&调用普通函数 this 指向 window 5.在构造函数的 prototype 中 this,指向当前对象的值
注释:在函数中 this 到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了,因为 this 的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境
总结
- 作用域的上下级,在函数创建时候就已经确定了。
- this 的指向问题取决于函数执行时候。
- 函数中自由变量的取值,需要创建这个函数时的作用域查找。