欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > js执行上下文

js执行上下文

2025/3/26 1:28:07 来源:https://blog.csdn.net/qq_53922901/article/details/146415991  浏览:    关键词:js执行上下文

目录

  • 执行上下文
    • js代码执行环境
    • 执行上下文生命周期

执行上下文

执行上下文Execution Context就相当于js代码执行的环境

js代码执行环境

  • 全局环境
  • 函数环境
  • eval函数环境(不常用)

对应的执行上下文有

  • 全局上下文
  • 函数上下文
  • eval函数上下文

在js代码开始运行时,会先生成全局上下文,然后遇到当前调用的函数生成此函数的上下文,并依次放入栈中

当进入一个执行环境时,它的执行上下文就会被创建,并被推入执行栈中(入栈);程序执行完成时,它的执行上下文就会被销毁,并从栈顶被推出(出栈),控制权交由下一个执行上下文。

因为 JavaScript 在执行代码时最先进入全局环境,所以处于栈底的永远是全局环境的执行上下文。而处于栈顶的是当前正在执行函数的执行上下文

当函数调用完成后,它就会从栈顶被推出,理想的情况下,闭包会阻止该操作。

当我们使用递归函数不限制停止条件时,就会导致栈溢出

// 递归调用自身
function foo() {foo();
}
foo();
// 报错: Uncaught RangeError: Maximum call stack size exceeded

执行上下文生命周期

执行上下文的生命周期有两个阶段:

  1. 创建阶段(进入执行上下文):函数被调用时,进入函数环境,为其创建一个执行上下文,此时进入创建阶段。
  2. 执行阶段(代码执行):执行函数中代码时,此时执行上下文进入执行阶段。

创建阶段

创建阶段要做的事情主要如下:

  1. 创建变量对象(VO:variable object

    • 确定函数的形参(并赋值

    • 函数环境会初始化创建 Arguments对象(并赋值

    • 确定普通字面量形式的函数声明(并赋值

    • 变量声明,函数表达式声明(未赋值

  2. 确定 this 指向(this 由调用者确定

  3. 确定作用域(词法环境决定,哪里声明定义,就在哪里确定

执行阶段

  1. 变量对象赋值
    • 变量赋值
    • 函数表达式赋值
  2. 调用函数
  3. 顺序执行其它代码

例如(伪代码如下)

function fn(a) {// 函数内容var m = 1;var a = a;var f = () => {}// 函数被调用,生成函数上下文// 创建变量对象{// 确定形参,赋值a: 3,// 舒适化传教 Arguments 对象,赋值arguments : { 0 : 3, length : 1; },// 确定普通字面量的函数声明,赋值f: undefined,// 变量声明m: undefined}// 确定this指向// 这个函数this指向全局// 确定作用域// 在本函数作用域// 进行执行阶段// 创建变量对象{// 确定形参,赋值a: 3,// 舒适化传教 Arguments 对象,赋值arguments : { 0 : 3, length : 1; },// 确定函数引用f:  () => {},// 变量赋值m: 1}// 确定this指向// 这个函数this指向全局// 确定作用域// 在本函数作用域
}fn(3);

我们看到,只有在代码执行阶段,局部变量才会被赋予具体的值。在建立阶段局部变量的值都是 undefined

这其实也就解释了变量提升的原理。

以下代码会输出什么

(function () {console.log(typeof foo);console.log(typeof bar);var foo = "Hello";var bar = function () {return "World";}function foo() {return "good";}console.log(foo, typeof foo);
})()

使用同样的方法来分析

(function () {console.log(typeof foo);console.log(typeof bar);var foo = "Hello";var bar = function () {return "World";}function foo() {return "good";}console.log(foo, typeof foo);// 函数开始调用,创建函数上下文// 创建变量对象{// 没有形参// arguments对象// 函数变量bar: undefined,// 变量,开始为undefined,后来创建了function foo() {//    return "good";//}// 这样创建的函数foo本身就指向自己foo: (){return "good";}}// this指向// 确定作用域// 进入执行阶段console.log(typeof foo);	// 'function'console.log(typeof bar);	// 'undefined'// 变量对象{// 没有形参// arguments对象// 确定函数指向bar: function () {return "World";},foo: () {return "good";},// 变量赋值foo: "Hello"	}// this指向// 确定作用域console.log(foo, typeof foo);// 输出 'Hello'  'string'
})()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词