博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从JavaScript执行上下文理解变量提升
阅读量:5731 次
发布时间:2019-06-18

本文共 1876 字,大约阅读时间需要 6 分钟。

一直在看JavaScript的书,有几个知识点对新手来说很疑惑:

  1. 执行上下文
  2. 作用域链
  3. this

JavaScript是一门解释性语言,不需要编译,是可以直接拿到运行环境中运行。

执行上下文

  要解释执行上下文就先得说说JavaScript的内存机制;虽然JavaScript的运行环境一般都自带了GC装置,所以不用太操心内存泄漏的这个蛋疼的问题。但是当我们每当声明一个变量时,这个变量到底存在内存中的哪里?一般来说在JavaScript中基础数据类型(null  undefined string number Boolean)是存在栈中,而引用类型(array object)是存在堆内存中。eg:

var a1 = 0;   // 变量对象var a2 = 'this is string'; // 变量对象var a3 = null; // 变量对象var b = { m: 20 }; // 变量b存在于变量对象中,{m: 20} 作为对象存在于堆内存中var c = [1, 2, 3]; // 变量c存在于变量对象中,[1, 2, 3] 作为对象存在于堆内存中

从图中可以看出引用类型的的值是保存了一个堆内存中的一个地址,所以每次操作时都是对源数据进行操作!

而执行上下文呢?根据《JavaScript高级编程》中指出,EC(执行时环境)中主要有三部分  1:VO(变量对象)  2:SC(作用域链)   3:this

在运行JavaScript时最先入栈的就是全局EC,若有其他的新的执行环境创建则依次入栈,运行完时则出栈。

 

 

变量对象的创建,依次经历了以下几个过程。

 

  1. 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。

  2. 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。

  3. 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

总的来说就是function优先级比var高,var声明的变量永远都是undefined,而对于引用类型和函数则是堆内存地址! 

 
// demo01function test() {    console.log(a);    console.log(foo());    var a = 1;    function foo() {  return 2;    }}test();

在上例中,我们直接从test()的执行上下文开始理解。全局作用域中运行test()时,test()的执行上下文开始创建。为了便于理解,我们用如下的形式来表示

 

创建过程testEC = {    // 变量对象    VO: {},    scopeChain: {},    this: {}}// 因为本文暂时不详细解释作用域链和this,所以把变量对象专门提出来说明// VO 为 Variable Object的缩写,即变量对象VO = {    arguments: {...},    foo: 
// 表示foo的地址引用 a: undefined}

未进入执行阶段之前,变量对象中的属性都不能访问!但是进入执行阶段之后,变量对象转变为了活动对象,里面的属性都能被访问了,然后开始进行执行阶段的操作。

这样,如果再面试的时候被问到变量对象和活动对象有什么区别,就又可以自如的应答了,他们其实都是同一个对象,只是处于执行上下文的不同生命周期。

// 执行阶段VO ->  AO   // Active ObjectAO = {    arguments: {...},    foo: 
,    a: 1}

因此,上面的例子demo1,执行顺序就变成了这样

function test() {    function foo() {        return 2;   }    var a;    console.log(a);   console.log(foo()); a = 1;}test();

 

 

 

转载于:https://www.cnblogs.com/duyingxuan/p/6406380.html

你可能感兴趣的文章
C++Primer_笔记_异常处理
查看>>
分区交换 alter table exchange partition 在线表 历史表交换
查看>>
思科三层交换 HSRP 热备 配置方法
查看>>
zabbix详解:(二)添加被监控机器
查看>>
设计模式单列
查看>>
人像模式的灯光效果?iPhone 8开挂袭来
查看>>
Linux下MongoDB安装与配置
查看>>
DSL配置(PPPOA)
查看>>
WEBRTC执行流程
查看>>
Spring Boot 入门系列
查看>>
Spring Cloud版——电影售票系统<六>使用 Spring Cloud Config 统一管理微服务配置
查看>>
Java not support java EE1.3
查看>>
iptables规则备份及恢复、firewalld九个zone,service的操作
查看>>
www.conf配置文件的参数详解
查看>>
如何实现邀请好友帮抢票功能?
查看>>
深圳联通特邀湖北籍企业参观公司总部大楼举行
查看>>
告警系统主脚本、告警系统配置文件、告警系统监控项目
查看>>
Python 和 PyCharm 在 windows10 环境的安装和设置
查看>>
B-树,B+树与B*树的优缺点比较
查看>>
C语言入门基础之数组——数学和编程的完美结合(图)
查看>>