变量对象

先来说说什么是变量对象。变量对象中又存储了什么东西吧。

JavaScript中的运行环境包含全局运行环境和函数运行环境这两种,每进入到一个运行环境都会创建一个变量对象,这个对象中记录了在当前运行环境中能够訪问到的变量,它们以变量对象的属性形式存在。也就是说这个变量对象成为“作用域”这个抽象概念的实体。

同一时候,变量对象中的属性记录是有一定先后顺序的。而且属性值究竟是实际的值还是undefined也是分阶段的(进入上下文(函数開始调用,但还未运行内部的详细代码)。运行代码阶段)。

1. 在全局环境中:

(1)函数声明

(2)变量声明—其值为undefined,一直到运行到这条语句的时候才被赋予详细值。

2. 函数环境中:

在进入运行环境的时候,变量对象会进行例如以下初始化:

(1)arguments对象,对象中的值被赋予详细的实參值

(2)函数的形參:变量对象的一个属性。其属性名就是形參的名字。其 值就是实參的值;对于没有传递的參数,其值为undefined。

(3)函数声明:变量对象的一个属性。其属性名和值都是函数对象创建出来的,其值为指向某个函数对象的引用;

(4)变量声明:变量对象的一个属性,其属性名即为变量名。其值为undefined。

而在运行到函数内部的详细某个语句的时候。上面所述的值为undefined的变量。其值都会被赋予详细的值。

总结一句话:在进入上下文的时候(比方进入到一个全局环境或者是调用某个函数),变量对象除了arguments。函数的声明,以及參数被赋予了详细的属性值,其他的变量属性默认的都是undefined。

关于声明提升

**

JavaScript具有“声明提升”的特性。使用function或var进行的声明会被提升至当前作用域的顶端。

**

事实上理解这句话能够从进入到一个运行环境后都发生了什么来看,正如上面所说。进入到一个上下文后,声明的函数(值为函数对象的引用)和变量(其值为undefined)都被记录在了变量对象中。到了运行代码阶段,一边在作用域链中搜索标识符,一边运行到某个语句后把原本进入上下文阶段值为undefined的变量更换为详细的值。

函数声明提升

看看第(3)条,在进入到运行环境的时候。函数声明就会被加入到变量对象中,其相应的属性值是指向所声明的函数对象的引用,假设在函数声明的语句之前存在一条函数调用语句,引擎会在作用域中搜索该标示符。而且在变量对象中成功查找到了声明的函数名,其值也是存在的,即指向创建的函数对象的引用。因此这样写代码不会报错,成功调用了函数。

而通过函数表达式方式,也就是说不是以function开头,而是把函数赋值给了某个变量,由于在进入上下文阶段是不会给变量赋予详细的值的(參看第(4)条),所以这个时候该变量的值为undefined,要等到运行代码阶段,运行到这条语句后才会将其值更换为指向函数对象的引用,因此假设调用函数的语句在前面则会报错。此时在变量对象中搜索标识符。其值还是undefined,当然不能成功调用了。

再来看一个变量声明提升的样例

var a = "Hello";
function b() {
alert(a); //undefined
var a = "World";
alert(a); //World
}
b();

为什么运行了b(),第一个alert(a)是undefined呢?来看看进入到全局运行环境中发生了什么。全局环境的变量对象被填充为:

VO={

       b:指向一个函数对象的引用,

       a:undefined—>运行到该句话后变成”hello”

}

再来看看调用b()发生了什么,其变量对象被填充为:

VO={

        arguments:{},

        a:undefined—->运行到详细语句后才被赋值为“world”

}

注意到第一次运行到 alert(a)时会在当前作用域中搜索标识符a,发现已经存在一个a(则不会再沿着作用域链往外层搜索了),其值是undefined。而运行到var a = “World”;时则被替换为了详细的值。

假设在b中去掉var。则会沿着作用域链搜索到全局环境中的变量a。那么两个alert(a)都会输出“hello”。

參考资料:javascript 运行环境。变量对象,作用域链

JavaScript中的作用域与变量声明提升

JavaScript的作用域和变量对象的更多相关文章

  1. javascript执行上下文和变量对象

    执行上下文(execution context): 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念. js语言是一段一段的顺序执行,这个“段”其实就是我们说的这个执行上 ...

  2. javascript 执行环境,变量对象,作用域链

    前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体. 通过上网查资料,特来总结,以备回顾和修正. 要讲的依次为: EC( ...

  3. JavaScript——执行环境、变量对象、作用域链

    前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体.通过上网查资料,特来总结,以备回顾和修正. 目录: EC(执行环境或 ...

  4. 【转】javascript 执行环境,变量对象,作用域链

    这篇文章比较清晰的解释了一些作用域链相关的概念,忍不住收藏了 原文地址:http://segmentfault.com/a/1190000000533094 前言 这几天在看<javascrip ...

  5. 再看javascript执行上下文、变量对象

    突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...

  6. JavaScript词法作用域与调用对象

    关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...

  7. JavaScript 执行环境 与 变量对象

    什么是JS的执行环境? function funA(){ //一段代码静静的躺在这里,不能叫执行环境 } funA(); //当代码开始执行以后,系统会将它存入执行栈,并为他准备好足够的内存空间使用 ...

  8. js中函数的创建和调用都发生了什么?执行环境,函数作用域链,变量对象

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/26/js%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E ...

  9. JavaScript的作用域和闭包

    首发于:https://mingjiezhang.github.io/ 闭包和作用域有着千丝万缕的联系. js的作用域 具体的作用域我就不展开叙述了.其中很重要的两点就是:js的作用域链机制和函数词法 ...

随机推荐

  1. H2内存数据库 支持存储到文件

     准备工作 1.下载JDK(本人下载的版本号为JDK1.7).环境变量设置JAVA_HOME.设置PATH(%JAVA_HOME%\bin%). 2.下载并解压:h2-2014-07-13.zip ...

  2. 微凉大大,教你一步一步在linux中正确的安装Xcache加速php。

    首先,强烈吐槽,百度上的教程,都左复制右复制的,乱七八糟,缺东缺西的.借此微凉大大我提供我苦心整理好的教程.以便各位小菜能顺利的使用Xcache加速php,假设看完了,也操作了,还是失败了的话,请联系 ...

  3. 序列化TList of objects(摘自danieleteti的网站)

    Some weeks ago a customer asked to me if it is possibile serialize a TList of objects. “Hey, you sho ...

  4. VC++ WIN32 sdk实现按钮自绘详解 之二.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  5. SPOJ375(树链剖分)

    题目:Query on a tree 题意:给定一棵树,告诉了每条边的权值,然后给出两种操作: (1)把第i条边的权值改为val (2)询问a,b路径上权值最大的边 分析:本题与HDU3966差不多, ...

  6. Ray Through Glasses

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30506#problem/T 题意:给你一束光,问你在一个三层的平面类传递n次的种数: 仔 ...

  7. 14.4.3.1 The InnoDB Buffer Pool

    14.4.3.1 The InnoDB Buffer Pool 14.4.3.2 Configuring Multiple Buffer Pool Instances 14.4.3.3 Making ...

  8. nginx+tomcat负载均衡策略

    測试环境均为本地,測试软件为: nginx-1.6.0,apache-tomcat-7.0.42-1.apache-tomcat-7.0.42-2.apache-tomcat-7.0.42-3 利用n ...

  9. Cocos2d-x 3.1.1 学习日志8--2分钟让你知道cocos2d-x3.1.1 文本类别

    实际上文本经常使用的三个,LabelTTF,LabelBMF和LabelAtlas.而他们使用非常相似.所以,你会只举一反三,非常快就能够掌握了. <span style="font- ...

  10. pinyin4j的使用

    pinyin4j的使用   pinyin4j是一个功能强悍的汉语拼音工具包,主要是从汉语获取各种格式和需求的拼音,功能强悍,下面看看如何使用pinyin4j.     import net.sourc ...