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 { } ...
随机推荐
- 深度学习系列之ANN
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3F0aGFoYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- Light OJ 1080 - Binary Simulation
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1080 1080 - Binary Simulation PDF (Englis ...
- uwsgi和wsgi
一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作为HTTP响应的Body发送给浏览器: 浏览器收到HTTP响应,从HTTP Bo ...
- CUDA笔记(11)
CUDA提供了一种cudaEvent_t的类型,这种类型Event可以统计GPU上面某一个任务或者代码段的精确运行时间 使用常量内存的光线跟踪器的性能比使用全局内存的性能提升了50% __consta ...
- Android中的Junit测试
在开发中Junit测试可以很方便的帮助开者尽可能早的发现并处理问题,而且使用也非常简单,只需要导入Junit测试相关的jar包并创建测试类,就可以对业务功能进行测试,而不用为了测试在代码中添加输出语句 ...
- <Sicily>Fibonacci
一.题目描述 In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + Fn-2 for n ≥ 2. For exampl ...
- js封装each函数
function each(ele,callback){ if(Object.prototype.toString.call(ele) == "[object Array]"){ ...
- Linux启动用户空间-init初始化进程
- 并查集 (Union Find ) P - The Suspects
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...
- JavaScript设计模式(biaoyansu)
1.构造器模式——创建类模式 ES6:class Student{ constructor(score,quality){ this.score = score this.quality = qu ...