JS的解析与执行过程—全局预处理阶段之全局词法环境对象
问题:有如下代码
var a = 1;
function pop() {
alert(a);
var a = 5;
}
pop();//执行结果,弹出undefined
这段代码的执行结果为undefined,为什么呢?
JS的解析与执行并不是读一行,处理一行,读一行,处理一行这样进行的,而是分为两个阶段:
1、预处理阶段;
2、执行阶段;
然后分别以全局和函数内部的局部代码而言:
1、全局预处理
在解析JS代码的时候,首先会创建一个全局LexicalEnviroment{ }(词法环境)对象
接下来扫描JS代码里面的两个部分:
a、用声明的方式创建的函数;
b、用var定义的变量;
扫面完毕后将这些变量及函数添加到全局的词法环境对象里面去;
LexicalEnviroment: {
a: undefined,
b: undefined,
test: 对函数的一个引用
}
//用声明的方式创建的函数
function test(params) {
}
//用函数表达式创建的函数
var test1 = function(params) {
}
//用var定义的变量
var a = 5;
var b;
//其他变量
c = 6;
定义一个声明函数和一个函数表达式来证明这一点,代码如下:
f();
g(); function f() {
console.log("ff");
}
var g = function() {
console.log("gg");
}
得到如下结果:
ff
e:\Code\JavaScript\day03\test2.js:2
g();
^ TypeError: g is not a function
函数f被正常执行,而函数g报错了
因为在预处理阶段,函数f的引用被放在LexicalEnviroment对象中了,而g没有,所以在调用时函数g()并不存在,所以报错。
改一下位置,这样就对了
f();
var g = function() {
console.log("gg");
}
g(); function f() {
console.log("ff");
}
这点在var定义变量上的体现:
console.log(a);
console.log(b); var a = 5;
b = 6;
这段代码的执行结果如下:
undefined
e:\Code\JavaScript\day03\test3.js:2
console.log(b);
^ ReferenceError: b is not defined
可见,如上所说,以var方式定义的a被添加到全局LexicalEnviroment{ }(词法环境)对象中了,其值为undefined,而直接定义的b此时不存在,所以报错。
这就是全局预处理阶段的过程。
声明:
关于全局的词法环境对象LexicalEnviroment,在浏览器中就约等于window对象,该对象是属于JS解析器的东西,在不同的地方叫法不同,比如在Node中称为Execute Context(运行上下文对象)或许更合适一点,在ECMA -262标准中有其解释,但我们无需关心其具体含义,只是有这个概念便可。
JS的解析与执行过程—全局预处理阶段之全局词法环境对象的更多相关文章
- JS的解析与执行过程—函数预处理
声明:之所以分为全局预处理与函数预处理,只是为了理解方便,其实在实际运行中二者是不分先后的. 函数预处理阶段与全局预处理的差别: 函数每调用一次,就会产生一个LexicalEnviroment对象,在 ...
- JS的解析与执行过程
JS的解析与执行过程 全局中的解析和执行过程 预处理:创建一个词法环境(LexicalEnvironment,在后面简写为LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处 ...
- JS的解析与执行过程—全局预处理阶段之命名冲突的处理策略
有如下代码: <body> <script> alert(f); function f() { console.log("fff"); } var f = ...
- js全局的解析与执行过程
先看下面实例的执行结果: alert(a);//undefined alert(b);//报错 alert(f);//输出f函数字符串 alert(g);//undefined var a = 1; ...
- js函数的解析与执行过程
function f(a,b,c){ alert(a);//函数字符串 alert(b); var b = 5; function a(){ } } f(1,2); //预处理 lexicalEnvi ...
- JS引擎线程的执行过程的三个阶段(二)
继续JS引擎线程的执行过程的三个阶段(一) 内容, 如下: 三. 执行阶段 1. 网页的线程 永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS引 ...
- JS引擎线程的执行过程的三个阶段(一)
浏览器首先按顺序加载由<script>标签分割的js代码块,加载js代码块完毕后,立刻进入以下三个阶段,然后再按顺序查找下一个代码块,再继续执行以下三个阶段,无论是外部脚本文件(不异步加载 ...
- openWRT自学---基于backfire版本,分析其Make命令的执行过程和各阶段的主要产物
准备阶段:从SVN下载backfire的编译环境(位置是:svn co svn://svn.openwrt.org/openwrt/branches/backfire),然后按照openWRT的要求, ...
- js的解析--预处理(三)
js的解析与执行过程 分全局 {预处理阶段和执行阶段} 函数{预处理函数和执行阶段} 1/创建词法环境(环境上下文) LexicalEnvironment === window { } ...
随机推荐
- Springmvc JSON交互
先上前端javascript.ajax代码 <pre name="code" class="javascript"> function testAj ...
- httpd: Could not reliably determine the server's fully qualified domain name
[root@luozhonghua sbin]# service httpd start Starting httpd: httpd: apr_sockaddr_info_get() failed f ...
- What's Wrong With Hue Oozie Editor?
本文原文出处: http://blog.csdn.net/bluishglc/article/details/47021019 严禁不论什么形式的转载,否则将托付CSDN官方维护权益! First, ...
- 【android】解决Viewpager设置高度为wrap_content无效的方法
今天发现设置viewpager高度为wrap_content时并没作用.stackoverflow给出了解决方式,就是自己定义viewpager,重写onMesure()方法: public clas ...
- POJ 3122 Pie 二分答案
题意:给你n个派,每个派都是高为一的圆柱体,把它等分成f份,每份的最大体积是多少. 思路: 明显的二分答案题-- 注意π的取值- 3.14159265359 这样才能AC,,, //By Sirius ...
- java9新特性-17-智能Java编译工具
1.官方Feature 139: Enhance javac to Improve Build Speed. 199: Smart Java Compilation, Phase Two 2.使用说明 ...
- hiho149周 - 数据结构 trie树
题目链接 坑点:accept和deny的ip可能相同,需加个判断 #include <cstdio> #include <cstdlib> #include <vecto ...
- ML words
samples:样本 multi-dimensional entry / multivariate data:多属性记录 features:特征,属性 supervised learning:监督学习 ...
- vue中的三级联动
1.template里面的内容 2.js里面的内容 3.函数怎么写? 这是一个省市区的三级联动,首先你要传递中国的id,这样才能获取到所有的省份,所以在vue的项目中,我需要发一次进页面就请求(来得到 ...
- Http协议与TCP协议理解(转载的)
TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.Http会通 ...