IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript中的上下文环境 -> 正文阅读

[JavaScript知识库]JavaScript中的上下文环境

1、什么是上下文

上下文(Context)是程序运行的环境,在上下文中存储了一段程序运行时所需要的全部数据。在面向对象的编程语言中,上下文通常是一个对象,所以也被称为上下文对象。

在之前的课程中我们讲到过,程序中的变量存储在栈区,准确的说变量存储在了上下文对象中,而上下文对象保存在了栈中。开始执行一段程序时,它的上下文对象就会被创建,并被推入栈中(入栈);程序执行完成时,它的上下文对象就会被销毁,并从栈顶被推出(出栈)。

img

栈结构是一种先进先出的数据存储结构,通过栈这种特殊的数据结构可以确保程序中的变量在被使用时满足就近原则,避免数据混乱的问题,接下来我们就详细的了解,JS是如何利用上下文对象和栈来达到这个目的的。

img

小结:

上下文对象在一段程序执行之前创建

创建好上下文对象之后,会将该对象压入栈中

在程序执行的过程中,js总会从栈顶查找所需的数据

当程序执行结束,销毁上下文并出栈

2、上下文的分类

首先上下文对象分为两类,一种是全局上下文对象,一种是函数上下文对象

全局上下文对象是在开始执行一段javascript代码时所创建的上下文对象,在html环境中,该上下文对象就是window对象。在node环境中为global对象。创建完上下文对象之后,该对象会入栈。全局上下文对象有且只有一个,只有当浏览器关闭时,全局上下文对象才会出栈。

函数上下文对象是在一个函数开始执行时所创建的上下文对象,创建完该对象以后,该对象同样的会入栈,当函数执行完毕,函数上下文对象出栈。每一次函数的调用都会创建新的函数上下文对象并入栈,哪怕是同一个函数的多次调用依然如此。

在秩序执行过程中所需要的数据,都会从栈顶的上下文对象中获取。

请看下面一段代码:

<Script>
//1.全局上下文对象入栈
var v=10;
console.log(v);//2.从栈顶的上下文中获取数据v
function f1(){
    var v1=1;
    console.log(v1);//4.从栈顶的上下文中获取数据v1
    f2();//5.f2函数上下文入栈
    //8.f1函数上下文出战
}
function f2(){
    var v2=2;
    console.log(v2);//6.从栈顶的上下文中获取数据v2
    //7.f2函数上下文出栈
}
f1();//3.f1函数上下文入栈
</script>

现场图示:

img

3、上下文对象的创建过程

思考:为什么在函数内可以使用全局变量呢?var变量提升是怎么造成的?函数定义的不同方式有何异同?这些问题的答案都在这个上下文对象创建过程中。

上下文对象在创建时,会在内部创建两个对象:词法环境对象和变量环境对象。

上下文对象结构:

Context={
    词法环境对象:{
        
    },
    变量环境对象:{
    
	}
}

在词法环境对象中存储所有以let、const声明的变量以及所有的函数。而在变量环境对象中只存储以var声明的所有变量。值得注意的是由于函数具备参数,所以在函数的上下文对象的词法环境对象中还存储了一个arguments对象用于存储参数数据。

例如:如下代码

var v1=10;
let v2=20;
function f(num){
    var v3=30;
    let v4=40;
    function f1(){

    }
}
f(10);

上下文结构如下:

全局上下文对象结构:

GlobalContext={
    词法环境对象:{
        v2:,
        f:},
    变量环境对象:{
    	v1:}
}

函数上下文对象:

FunctionContext={
    词法环境对象:{
        v4:,
        f1:,
        arguments:[参数]
    },
    变量环境对象:{
    	v3:}
}

现场图示:

img

上下文对象在创建的过程中将变量和函数数据存储在了自己内部,那么此时各种不同的变量和函数的值是什么呢?JS针对不同的变量和函数采用了不同的方式来处理。

let、const在上下文对象的创建阶段不会被初始化,在代码执行阶段才会被赋值

var在上下文对象的创建阶段会被初始化为undefined。

表达式函数如果用let声明则不会被初始化,表达式函数如果用var生命则被初始化为undefined。

声明式函数在对象的创建阶段会被赋值为函数本身

函数的参数在创建阶段已经被赋值为实参

也就是说上面的代码对应的上下文对象,在上下文对象的创建阶段结构如下:

全局上下文对象结构:

GlobalContext={
    词法环境对象:{
        v2:未初始化,
        f:function f(){}
    },
    变量环境对象:{
    	v1:undefined
	}
}

函数上下文对象:

FunctionContext={
    词法环境对象:{
        v4:未初始化,
        f1:function f1(){},
        arguments:[10]
    },
    变量环境对象:{
    	v3:undefined
	}
}

判断如下代码执行结果:

console.log(a);
var a=10;

输出结果:undefined

原因:创建上下文对象的同时,已经对变量a进行了初始化并赋值为undefined。执行代码时从栈顶的上下文对象中找a,自然值为undefined。

console.log(a);
let a=10;

输出结果:img

原因:创建上下文对象的同时,let定义的变量不会被初始化。执行代码时从栈顶的上下文对象中找a,未初始化报错。

正因为这个原因,该程序一直执行到let a之前的部分,都是无法使用变量a的,这种情况就是暂时性死区。

f();
function f(){
    console.log(1);
}

输出结果:1

原因:创建上下文对象的同时,针对声明式函数已经将其初始化并赋值为函数本身。所以在执行f函数时可以正常调用。

c();
var c=function(){
    console.log(1);
}

输出结果:img

原因:创建上下文对象的同时,针对表达式函数的处理方式取决于前面变量的关键字,如果变量关键字为var,则会初始化并赋值为undefined,但是undefined并不是一个函数,所以报错。

f();
let f=function(){
    console.log(1);
}

输出结果:img

原因:创建上下文对象的同时,针对表达式函数的处理方式取决于前面变量的关键字,如果变量关键字为let,

则不会进行初始化,报错。

4、作用域与作用域链

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。从另一个角度讲就是指当前程序在执行时处于栈顶的上下文对象中是否能查找到该数据,那么如果在当前上下文对象中没有找到该数据怎么办呢?在上下文对象的创建过程中,会在词法环境对象和变量环境对象中定义一个属性(例如:outer),该属性的值为函数定义时所在的上下文对象,这个上下文一定是它的上级上下文对象。然后在查找数据时,如果在当前上下文对象中没有找到该数据,则会通过outer找到它的上级上下文对象,以此类推一直查找到全局上下文对象为止。这些上下文对象一起构成了一个作用域链条,它被称为作用域链。

var a=100;
function f(){
    var a=10;
    console.log(a);
    function f1(){
        console.log(a);
    }
    f1();
};
f();

现场图示:

img

无论你在学习上有任何问题,重庆蜗牛学院欢迎你前来咨询,联系QQ:296799112

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章           查看所有文章
加:2021-09-18 10:03:42  更:2021-09-18 10:05:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:34:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码