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 { } ...
随机推荐
- 如何查询mysql中是否表被锁
可直接在mysql命令行执行:show engine innodb status\G;(只能通过cmd或者shell登录mysql) 查看造成死锁的sql语句,分析索引情况,然后优化sql然后show ...
- 一、奇妙插件Tampermonkey的简单安装教程
奇妙插件Tampermonkey的简单安装教程 1.下载 对于浏览器而言,一般的功能并不能满足"特殊用户的需求".这时候就须要插件来帮忙了.那么讲到插件的支持多又常见的浏览器必定要 ...
- struts2入门(搭建环境、配置、示例)
转自:https://blog.csdn.net/u012862311/article/details/53412716 1.下载Struts2的jar包 下载地址:http://archive.ap ...
- [JZOJ4024] [佛山市选2015] 石子游戏 解题报告
Description Alice 和 Bob 总喜欢聚在一起玩游戏(T_T),今天他(她)们玩的是一款新型的取石子游戏.游戏一开始有N堆石子,Alice 和 Bob 轮流取出石子.在每次操作 ...
- CSS提高渲染速度的写法
写CSS的习惯,决定页面渲染速度的快慢,这一点在脑残的IE里更加明显.养成良好的习惯,乃至形成规范,会让你的页面更快速的加载,用户体验度更高,下面是零度逍遥总结的一些提高CSS渲染速度的写法,供大家参 ...
- 131.lambda表达式小结
C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下:[函数对象参数](操作符重载函数参数) mutable或exception声明->返回 ...
- prezi,mfc,toefl,java
1 用prezi做ppt然后讲 2 用mfc把算法封起来 3 做tpo,背单词 4 写java 哪个任务都很难办.而且脚还没好.
- 手把手教你进行R语言的安装及安装过程中相关问题解决方案
这篇文章旨在为R语言的新手铺砖引路,行文相对基础,希望对在R语言安装上有问题的小伙伴提供帮助和指引.一.什么是 R 语言R 编程语言被广泛应用在统计科学和商业领域. 在各种编程语言排名中 R 语言的排 ...
- 列表的所有的input,将它的值以键值对的形式存放到一个数组里
要求的格式 代码块 $('.btn-confirm').on('tap',function(){ var arr={}; var name = $("input[name='insuranc ...
- vue分页组件火狐中出现样式问题
分页的操作到了火狐浏览器会样式 怎么解决? 其实就是将input的type属性变成了text,因为number属性会变成上下的小箭头