最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

JS执行环境、作用域链、变量对象和活动对象的关系

来源:懂视网 责编:小采 时间:2020-11-27 19:33:01
文档

JS执行环境、作用域链、变量对象和活动对象的关系

JS执行环境、作用域链、变量对象和活动对象的关系:JS执行环境执行环境(Execution context,EC)或执行上下文,是JS中一个极为重要的概念执行环境分为三种(全局执行环境,函数执行环境,evel()执行环境)js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中EC的组成当Ja
推荐度:
导读JS执行环境、作用域链、变量对象和活动对象的关系:JS执行环境执行环境(Execution context,EC)或执行上下文,是JS中一个极为重要的概念执行环境分为三种(全局执行环境,函数执行环境,evel()执行环境)js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中EC的组成当Ja

EC的组成

当JavaScript代码执行的时候,会进入不同的执行环境(执行上下文),这些执行环境会构成了一个执行环境栈(执行上下文栈)(Execution context stack,ECS)。见下图:
1.png

变量对象

变量对象(VO):变量对象即包含变量的对象,除了我们无法访问它外,和普通对象没什么区别。变量对象存储了在上下文中定义的变量和函数声明

变量对象和活动对象(AO)

  1. 活动对象和变量对象其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,不可在 JavaScript 环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫 activation object

,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问。

  1. 活动对象是在进入函数执行环境时刻被创建的,它通过函数的 arguments 属性初始化。arguments 属性值是 Arguments 对象。

变量对象和活动对象的关系

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

它们其实都是同一个对象,只是处于执行环境的不同生命周期。

 AO 实际上是包含了 VO 的。因为除了 VO 之外,AO 还包含函数的 parameters,以及 arguments 这个特殊对象。也就是说 AO 的确是在进入到执行阶段的时候被激活,但是激活的除了 VO 之外,还包括函数执行时传入的参数和 arguments 这个特殊对象。

   AO = VO + function parameters + arguments

执行环境分析

全局执行环境是最外围的执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都作为window对象的属性和方法创建的。
js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。

eg:

 var scope = "global"; 
 function fn1(){
 return scope; 
 }
 function fn2(){
 return scope;
 }
 fn1();
 fn2();

演示如下:

2.png

[[Scope]] 作用域

变量的作用域

变量的作用域就两种:全局变量和局部变量

 全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:eg:
 var outerVar = "outer";
 function fn(){
 console.log(outerVar);
 }
 fn();//result:outer
 局部作用域:局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的
 function fn(){
 var innerVar = "inner";
 }
 fn();
 console.log(innerVar);// ReferenceError: innerVar is not defined
 注意:函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
 function fn(){
 age = 18;
 }
 fn();
 console.log(age);// 18

再来看一个有趣的现象:

 var scope = "global";
 function fn(){
 console.log(scope);//result:undefined
 var scope = "local";
 console.log(scope);//result:local;
 }
 fn();

分析:第一个输出居然是undefined,原本以为它会访问外部的全局变量(scope=”global”),但是并没有。这可以算是javascript的一个特点,只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”,他就等价于下面的代码:

 var scope = "global";
 function fn(){
 var scope;//提前声明了局部变量
 console.log(scope);//result:undefined
 scope = "local";
 console.log(scope);//result:local;
 }
 fn();

[[Scopr Chain]] 作用域链

理解:根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,这就是作用域链

上面给出了环境变量。下面仔细分析下作用域链

当某个函数第一次被调用时,就会创建一个执行环境(execution context)以及相应的作用域链,并把作用域链赋值给一个特殊的内部属性([scope])。然后使用this,arguments(arguments在全局环境中不存在)和其他命名参数的值来初始化函数的活动对象(activation object)。当前执行环境的变量对象始终在作用域链的第0位。以上述执行环境分析的小例子为例进行图解:当第一次调用fn1时。

3.png

解析:可以看到fn1活动对象里并没有scope变量,于是沿着作用域链(scope chain)向后寻找,结果在全局变量对象里找到了scope,所以就返回全局变量对象里的scope值。

再分析下面的代码:

 function outer(){
 var scope = "outer";
 function inner(){
 return scope;
 }
 return inner;
 }
 var fn = outer();
 fn();

4.png

总结

说实话,这节真的是很难,现在还是似懂非懂,不知道在学前端的小伙伴你们觉得呢?如果你们觉得这节学会了,可以给我留言,我是真心不懂这节的内容,希望有会的小伙伴可以给我点帮助!谢谢!

相关文章:

浅谈javascript中执行环境(作用域)与作用域链

老生常谈原生JS执行环境与作用域

相关视频:

js高级面向对象和组件开发视频教程

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

JS执行环境、作用域链、变量对象和活动对象的关系

JS执行环境、作用域链、变量对象和活动对象的关系:JS执行环境执行环境(Execution context,EC)或执行上下文,是JS中一个极为重要的概念执行环境分为三种(全局执行环境,函数执行环境,evel()执行环境)js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中EC的组成当Ja
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top