【JavaScript】4、执行环境、变量对象与声明提前

这段时间一直在看一些关于JavaScript的书,看到不明白的地方就满世界搜解答,结果今天晚上在搜索一个奇怪的语法的时候不小心点开一道面试题,是一道考察作用域的十年老题,于是我试着做了一下,果断被坑,结束后看解析,看得也不是很明白,于是赶紧回去看基础书,结果发现以前很多自己一眼扫过的知识点自己完全没有掌握,瞬间后悔万分,所以趁势赶紧重新学一下,同时把这些这些点记录下来。

原题是这样的:

var tt = ‘aa‘;
function test(){
alert(tt);
var tt = ‘dd‘;
alert(tt);
}
test();

答案是undefined,dd。

刚刚看到答案的时候感觉坑爹无比,后面看解析,感觉也是云里雾里,不过好在知道去哪里找答案,这题主要涉及执行环境、变量对象、声明提前等知识点,这里简单回顾一下

执行环境定义了变量或函数有权访问的其它数据,决定了他们各种的行为。每个执行环境都拥有一个与之关联的变量对象。环境中定义的所有变量和函数都保存在这个环境中。然而我们无法直接访问这个对象。

全局执行环境一般被认为是window对象,所以所有的全局变量和函数也都是作为window的属性和方法来创建的。

每个函数都有自己的执行环境,当执行流进入一个函数时,函数的执行环境就会被推入一个环境栈中,而在函数执行之后,栈将环境推出,把控制权交还给之前的执行环境。

当代码在一个执行环境中执行时,会创建变量对象的一个作用域链,作用域链的作用,是保证对执行环境有权访问的变量和函数的有序访问。

作用域链的最前端总是当前执行环境的变量对象,其次是上一层执行环境的变量对象,再其次是上上一层的执行环境的变量对象,知道全局环境。

如果执行环境是函数,则将其活动对象作为变量对象,活动对象最开始时只包含一个arguments对象,函数内部定义的变量和函数则会在函数执行前加入到这个活动对象中。

声明提前是指解析器在解析一个作用域中的代码时,会将变量和函数的定义提前到作用域的顶端,而赋值则留在原处。

好了,有了以上的理论知识,我们再来看这道题。

首先,声明一个全局变量tt,并复赋值为‘aa‘。

然后,创建函数test(),根据上面讲到的内容,这个函数拥有一个自己的执行环境,并关联一个变量对象,这个变量对象拥有一个arguments对象,此时,这个arguments对象为null。在解析器解析这个函数时,会将函数中定义的变量和函数都添加到这个变量对象中,并把变量定义语句提前到作用域顶部。

之后在函数执行时,会创建作用域链,作用域链把函数自己的变量对象放在作用域链的最前端,后面是它的上一层作用域的变量对象,也就是window对象。此时两个变量对象都有一个变量tt,在前端的函数内部定义的tt会屏蔽掉全局的tt,然后根据声明提前,此时var tt=‘dd‘会被分割成两部分,声明部分(var tt)被提前到函数开头,而赋值语句(tt=‘dd‘)仍留在原地。此时执行第一个alert(tt)时会弹出undefined,因为此时tt只有声明,尚未赋值,而第二个alert会弹出dd,因为此时tt已经赋值好了。

时间: 2024-10-26 10:15:16

【JavaScript】4、执行环境、变量对象与声明提前的相关文章

从头开始学JavaScript (九)——执行环境和作用域

原文:从头开始学JavaScript (九)--执行环境和作用域 一.执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有与之关联的变量对象. 变量对象:保存着环境中定义的变量和函数. 作用域链:保证对执行环境有权访问的所有变量和函数的有序访问. 标识符解析:沿着作用域链一级一级地搜索标识符的过程. 通过例子来说明执行环境.变量对象以及作用域链: 1 <script type="text/javascript"> 2 var color =

JavaScript中执行环境和栈

在这篇文章中,我会深入理解JavaScript最根本的组成之一 : "执行环境(执行上下文)".文章结束后,你应该对解释器试图做什么,为什么一些函数/变量在未声明时就可以调用并且他们的值是如何确定的有一个清晰的认识. 什么是执行环境(执行上下文)当代码在JavaScript中运行的时候,代码在环境中被执行是非常重要的,它会被评估为以下之一类型来运行:全局代码:默认环境,你的代码第一时间在这儿运行.函数代码:当执行流进入一个函数体的时候.Eval代码:在eval()函数中的文本. 你可以

Javascript手记-执行环境和作用域

执行环境是javascript一个重要的概念,执行环境定义了变量有权访问其他数据决定了他们各自的行为,每个执行环境 都有一个与之关联的变量,环境中定义的所有变量和函数都保存在这个对象中,虽然我们编写的代码无法访问这个对象,但 解析器在处理数据时候会在后台使用. 全局执行环境是最外围的一个执行环境,根据ecmascript实现所在的宿主环境不同,表示执行环境的对象也不一样在 web浏览器中,全局执行环境被认为是window对象,因此所有的全局变量和函数都是作为window对象的属性和方法创建 的某

初探JavaScript(四)——JS另类的作用域和声明提前

前言:最近恰逢毕业季,千千万万的学生党开始步入社会,告别象牙塔似的学校生活.往往在人生的各个拐点的时候,情感丰富,感触颇深,各种对过去的美好的总结,对未来的展望.与此同时,也让诸多的老“园”工看完这些小年轻的文章后感触良多,不禁也要写上几笔,所以就出来了很多类似“毕业两年小记”.“毕业五年有感”…… 可能就是某篇博文的一句话,某碗心灵鸡汤就拨动了你心里的那根尘封已久的弦,让你情不自禁的点了个赞,还忍不住的要在下面评论区留下自己此刻心潮澎湃的印记. 我今天不是来送鸡汤的,鸡汤虽好,可不要贪杯哦.

深入理解javascript中执行环境(作用域)与作用域链

相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境.那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境.我们下来看一看如下代码,再进一步分析之. 1 2 3 4 5 6 7 8 9 10 11 <script><br>var name="zhuzhenwei"; functio

JavaScript之执行环境及作用域

执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.我们编写的代码是无法访问这个对象的,但解析器在处理数据时会在后台使用它. 全局执行环境是最外围的一个执行环境,在Web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法来创建的.某个执行环境中的所有代码执行完毕后,该环境就会被销毁,保存在其中的所有变量和函数定义也随之销毁. 每个函数都有自己

JavaScript(1)——变量、函数声明及作用域

这是我的第一篇博客文章,本人不才,文笔也不好,所以可能写的有点凌乱.有什么不对的地方还望见谅.不过每天进步一小步,总有一天会迈出那一大步.以下内容是我对变量.函数声明及函数表达式.作用域的理解. [变量]大意上来讲,变量就是所定义的一个可以用来保存值的占位符.定义变量时要使用var操作符. 变量所保存类型可以被改变,但不建议. var操作符定义的变量将成为该变量的作用域中的局部变量,在函数退出后,变量将被销毁. 若省略var操作符可以定义全局变量,不过在严格模式下会导致抛出ReferenceEr

JavaScript的作用域和变量对象

变量对象 先来说说什么是变量对象.变量对象中又存储了什么东西吧. JavaScript中的运行环境包含全局运行环境和函数运行环境这两种,每进入到一个运行环境都会创建一个变量对象,这个对象中记录了在当前运行环境中能够訪问到的变量,它们以变量对象的属性形式存在.也就是说这个变量对象成为"作用域"这个抽象概念的实体. 同一时候,变量对象中的属性记录是有一定先后顺序的.而且属性值究竟是实际的值还是undefined也是分阶段的(进入上下文(函数開始调用,但还未运行内部的详细代码).运行代码阶段

js内存空间 执行上下文 变量对象详解 作用域链与闭包 全方位解读this

内存空间:https://blog.csdn.net/pingfan592/article/details/55189622 执行上下文:https://blog.csdn.net/pingfan592/article/details/55189804 变量对象详解:https://blog.csdn.net/pingfan592/article/details/56009330 作用域链与闭包:https://blog.csdn.net/pingfan592/article/details/5