JavaScript的作用域和变量对象
变量对象
先来说说什么是变量对象。变量对象中又存储了什么东西吧。
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执行上下文和变量对象
执行上下文(execution context): 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念. js语言是一段一段的顺序执行,这个“段”其实就是我们说的这个执行上 ...
- javascript 执行环境,变量对象,作用域链
前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体. 通过上网查资料,特来总结,以备回顾和修正. 要讲的依次为: EC( ...
- JavaScript——执行环境、变量对象、作用域链
前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体.通过上网查资料,特来总结,以备回顾和修正. 目录: EC(执行环境或 ...
- 【转】javascript 执行环境,变量对象,作用域链
这篇文章比较清晰的解释了一些作用域链相关的概念,忍不住收藏了 原文地址:http://segmentfault.com/a/1190000000533094 前言 这几天在看<javascrip ...
- 再看javascript执行上下文、变量对象
突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...
- JavaScript词法作用域与调用对象
关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...
- JavaScript 执行环境 与 变量对象
什么是JS的执行环境? function funA(){ //一段代码静静的躺在这里,不能叫执行环境 } funA(); //当代码开始执行以后,系统会将它存入执行栈,并为他准备好足够的内存空间使用 ...
- js中函数的创建和调用都发生了什么?执行环境,函数作用域链,变量对象
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/26/js%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E ...
- JavaScript的作用域和闭包
首发于:https://mingjiezhang.github.io/ 闭包和作用域有着千丝万缕的联系. js的作用域 具体的作用域我就不展开叙述了.其中很重要的两点就是:js的作用域链机制和函数词法 ...
随机推荐
- APPCAN学习笔记003---原生开发与HTML5技术
APPCAN学习笔记003---原生开发与HTML5技术 技术qq交流群:JavaDream:251572072 1.HTML5的优势: HTML5强悍牢固的骨架 CSS3精致到每一个毛孔的皮 ...
- 一个计算器的C语言实现
今天在读<编译原理及实践>时.看到了一个简单的整数计算器的实现. 依照书上的思路,我略微进行了扩展: 1.从整数计算器扩展到小数计算器. 2.支持除法 3.支持空字符. 执行效果例如以下: ...
- Socket编程之聊天程序 - 模拟Fins/ModBus协议通信过程
设备控制软件编程涉及到的基本通信方式主要有TCP/IP与串口,用到的数据通信协议有Fins与ModBus. 更高级别的通信如.net中的Remoting与WCF在进行C/S架构软件开发时会采用. 本篇 ...
- RF+Selenium2Library+Sikuli集成环境搭建
Sikuli是通过截图来编写代码的脚本语言,他是对于Selenium不好处理的一些模态窗口.flash等的利器.废话少说,直接开始安装吧.安装RF+Selenium2Library的环境这里就不说了, ...
- 打造你自己ajax上传图片
今天,我们需要的图片上传插件,但是,互联网不提供符合他们的需要和易于使用的.所以我写了自己. 方法1,只使用jquery代码,.代码例如以下 <p> <label>上传图片&l ...
- ps中图层混合模式算法公式
网上已经有很多讲解ps的图层混合模式,有些不详细甚至是错误的,参考网上给出的公式及其自己在验证推倒的,给出27种的混合模式算法公式.也许存在一定的错误性,毕竟没有官方给出公式,只能说以供参考吧. 只考 ...
- 在Ubuntu上录制视频和编辑(很全)
Linux多媒体三剑客:GIMP,Inkscape,Blender3D Blender基金会制作的开源微电影Sintel:http://www.sintel.org/about电影采用Creative ...
- 14.3.5.1 An InnoDB Deadlock Example
14.3.5 Deadlocks in InnoDB 14.3.5.1 An InnoDB Deadlock Example 14.3.5.2 Deadlock Detection and Rollb ...
- make 2>&1 | tee log.txt之小析
前言 接触过linux的人,或多或少都会了解一点make 2>&1 | tee log.txt这个命令. 1. make是什么? make是linux下一个非常强大的命令,简单点就是你要 ...
- js关闭浏览器窗口事件
js关闭浏览器窗口 js关闭浏览器窗口,不弹出提示框.支持ie6+,火狐,谷歌等浏览器. <html> <head /> <body> <script typ ...