JS的解析与执行过程—全局预处理阶段之命名冲突的处理策略
有如下代码:
<body>
<script>
alert(f); function f() {
console.log("fff");
}
var f = 5;
</script>
</body>
不论var f 与function f 的先后顺序如何,该代码执行的结果总是弹出function f 的字符串,为什么呢?像这种函数与变量命名冲突时JS的处理原则又是什么?
在扫描函数声明与变量声明的时候,是先扫描函数声明(function fn()),后扫描变量声明(var a)的;
- 处理函数声明有冲突,会覆盖;
- 处理变量声明有冲突,会忽略;
上面代码中,由于先扫描函数声明,所以LexicalEnviroment对象中先存在了 f 指向函数的引用,然后扫描到变量的时候发现变量名冲突,忽略这个变量,所以总是弹出函数字符串。
也就是说,在JS中函数的优先级是高于变量的。相同优先级以后面的为准,不同优先级以级别高的为准。
然后当存在两个同名函数时,会覆盖,所以总是指向后一个函数的,这点就像声明两个同名变量一样。
总结:有如下代码:
<script>
alert(a);
// alert(b);
alert(f);
alert(g); var a = 5;
b = 6;
alert(b);
function f() {
console.log("fff");
}
var g = function() {
console.log("ggg");
}
alert(g);
</script>
这段代码在预处理阶段,分别扫描函数声明和变量声明,加入到全局对象window中:
window = {
f: 函数引用,
a: undefined,
g: undefined
}
注意,由于函数 g 是以函数表达式的方式声明的,所以在预处理时会当作一个变量,其值为undefined,所以上面代码执行结果为弹出undefined, f 的字符串表示, undefined
然后走过了var a = 5; b = 6;之后window对象变为:
window = {
f: 函数引用,
a: 5,
b: 6,
g: undefined
}
所以此时alert(b)弹出6;
因为在JS中不用var声明,直接写的变量默认为全局变量(window的),此时直接不用预处理而直接一步加到全局对象中,预处理的undefined被赋值。
然后走过函数f与函数g的表达式,此时g也指向函数,所以最后alert(g)弹出g的字符串。
JS的解析与执行过程—全局预处理阶段之命名冲突的处理策略的更多相关文章
- JS的解析与执行过程—全局预处理阶段之全局词法环境对象
问题:有如下代码 var a = 1; function pop() { alert(a); var a = 5; } pop();//执行结果,弹出undefined 这段代码的执行结果为undef ...
- JS的解析与执行过程—函数预处理
声明:之所以分为全局预处理与函数预处理,只是为了理解方便,其实在实际运行中二者是不分先后的. 函数预处理阶段与全局预处理的差别: 函数每调用一次,就会产生一个LexicalEnviroment对象,在 ...
- JS的解析与执行过程
JS的解析与执行过程 全局中的解析和执行过程 预处理:创建一个词法环境(LexicalEnvironment,在后面简写为LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处 ...
- js全局的解析与执行过程
先看下面实例的执行结果: alert(a);//undefined alert(b);//报错 alert(f);//输出f函数字符串 alert(g);//undefined var a = 1; ...
- JS引擎线程的执行过程的三个阶段(二)
继续JS引擎线程的执行过程的三个阶段(一) 内容, 如下: 三. 执行阶段 1. 网页的线程 永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS引 ...
- JS引擎线程的执行过程的三个阶段(一)
浏览器首先按顺序加载由<script>标签分割的js代码块,加载js代码块完毕后,立刻进入以下三个阶段,然后再按顺序查找下一个代码块,再继续执行以下三个阶段,无论是外部脚本文件(不异步加载 ...
- js函数的解析与执行过程
function f(a,b,c){ alert(a);//函数字符串 alert(b); var b = 5; function a(){ } } f(1,2); //预处理 lexicalEnvi ...
- openWRT自学---基于backfire版本,分析其Make命令的执行过程和各阶段的主要产物
准备阶段:从SVN下载backfire的编译环境(位置是:svn co svn://svn.openwrt.org/openwrt/branches/backfire),然后按照openWRT的要求, ...
- js的解析--预处理(三)
js的解析与执行过程 分全局 {预处理阶段和执行阶段} 函数{预处理函数和执行阶段} 1/创建词法环境(环境上下文) LexicalEnvironment === window { } ...
随机推荐
- vs解决方案里复制一个项目
首先,保证要复制的项目的整洁无垃圾文件: 然后,选“文件”/“导出模板”,起个名字: 再者,创建一个同类型的项目,这时项目模板里就会出现你刚才导出的项目了.
- Android开发学习之事件处理和Button具体解释
Android的事件处理机制: 1.基于监听器的事件处理 --- 组件绑定特定的事件监听器 --- 重点 2.基于回调的事件处理 --- 主要做法是重写Android组件特定的回调函数, ...
- Android使用ShowcaseView加入半透明操作提示图片的方法
http://beeder.me/2014/11/11/how-to-add-a-semi-transparent-demo-screen-using-showcaseview/ 这篇文章具体介绍了如 ...
- 创建一个Spring的HelloWorld程序
Spring IOC IOC指的是控制反转,把对象的创建.初始化.销毁等工作都交给Spring容器.由spring容器来控制对象的生命周期.下图能够说明我们传统创建类的方式和使用Spring之后的差别 ...
- java生成MD5校验码
在Java中,java.security.MessageDigest (rt.jar中)已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数.然后将此 128 位计 ...
- 9. IntelliJ Idea 集成svn 和使用
转自:http://www.cnblogs.com/zhanghaoliang/p/6206948.html 最近公司的很多同事开始使用IntelliJ Idea,便尝试了一下,虽然快捷键与eclip ...
- spring boot自动配置之jdbc
1.DataSource配置 1.1 默认配置application.xml spring.datasource.url=jdbc:mysql://localhost/test spring.data ...
- AIX 6.1 Oracle 10G 数据库GoldenGate实施
安装环境说明: 源端:AIX 6.1 10.190.1.215 目标端:Linux 10.191.1.10 1:源端创建goldengate 表空间. 表空间的要求:最小500m,大点3-5G,设置自 ...
- 6、json支持
package main import ( "encoding/json" "fmt") // Json 支持 type Response1 struct{ P ...
- docker切换默认镜像源
docker切换默认镜像源 基于 debian8 默认安装的 docker 镜像源是在国外,pull 镜像的时候奇慢无比,需要自己手动切换成国内的镜像源. 1. 修改配置文件 docker 默认的 ...