有如下代码:

 <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的解析与执行过程—全局预处理阶段之命名冲突的处理策略的更多相关文章

  1. JS的解析与执行过程—全局预处理阶段之全局词法环境对象

    问题:有如下代码 var a = 1; function pop() { alert(a); var a = 5; } pop();//执行结果,弹出undefined 这段代码的执行结果为undef ...

  2. JS的解析与执行过程—函数预处理

    声明:之所以分为全局预处理与函数预处理,只是为了理解方便,其实在实际运行中二者是不分先后的. 函数预处理阶段与全局预处理的差别: 函数每调用一次,就会产生一个LexicalEnviroment对象,在 ...

  3. JS的解析与执行过程

    JS的解析与执行过程 全局中的解析和执行过程 预处理:创建一个词法环境(LexicalEnvironment,在后面简写为LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处 ...

  4. js全局的解析与执行过程

    先看下面实例的执行结果: alert(a);//undefined alert(b);//报错 alert(f);//输出f函数字符串 alert(g);//undefined var a = 1; ...

  5. JS引擎线程的执行过程的三个阶段(二)

    继续JS引擎线程的执行过程的三个阶段(一) 内容, 如下: 三. 执行阶段 1. 网页的线程 永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS引 ...

  6. JS引擎线程的执行过程的三个阶段(一)

    浏览器首先按顺序加载由<script>标签分割的js代码块,加载js代码块完毕后,立刻进入以下三个阶段,然后再按顺序查找下一个代码块,再继续执行以下三个阶段,无论是外部脚本文件(不异步加载 ...

  7. js函数的解析与执行过程

    function f(a,b,c){ alert(a);//函数字符串 alert(b); var b = 5; function a(){ } } f(1,2); //预处理 lexicalEnvi ...

  8. openWRT自学---基于backfire版本,分析其Make命令的执行过程和各阶段的主要产物

    准备阶段:从SVN下载backfire的编译环境(位置是:svn co svn://svn.openwrt.org/openwrt/branches/backfire),然后按照openWRT的要求, ...

  9. js的解析--预处理(三)

    js的解析与执行过程  分全局  {预处理阶段和执行阶段}  函数{预处理函数和执行阶段}   1/创建词法环境(环境上下文) LexicalEnvironment   === window { } ...

随机推荐

  1. 兼顾php和jquery新版本的checkbox的写法

    <input type="checkbox" class="scate_item" name="scategories[]" valu ...

  2. hdu 4786 Fibonacci Tree 乱搞 智商题目 最小生成树

    首先计算图的联通情况,如果图本身不联通一定不会出现生成树,输出"NO",之后清空,加白边,看最多能加多少条,清空,加黑边,看能加多少条,即可得白边的最大值与最小值,之后判断Fibo ...

  3. 部署OGG时字符集转换问题--oracle to oracle已验证,其他异构环境应当也适用

    之前在安装OGG总是遇到字符集问题,尤其是多源端对一个目标端时,源端字符集不同,导致出现字符集问题 无法同步数据,查阅了大量的园子资料,都说要设置复制或抽取进程中SETENV (NLS_LANG=AM ...

  4. java 自定义实现base64编码转换

    1.base64编码转换 所谓base64编码,即按照规则把字符转化为"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 ...

  5. 严重: 文档无效: 找不到语法。 at (null:2:19)

    1.错误描写叙述 严重: 文档无效: 找不到语法. at (null:2:19) org.xml.sax.SAXParseException; systemId: file:/D:/MyEclipse ...

  6. Win 10最大的亮点不是免费而是人工智能

    7月27日,日本知名作家Manish Singh发表文章.题为"Eight Reasons Why You Should Upgrade to Windows 10",文中例举下面 ...

  7. java基本数据类型复习

    1.基本取值范围及对应封装器(参考:http://www.cnblogs.com/Free-Thinker/p/4573068.html): 简单类型 boolean byte char short ...

  8. Dictionaries and lists

    Lists can appear as values in a dictionary. For example, if you were given a dictionary that maps fr ...

  9. C# 引用DLL版本冲突

    已解决,到官网上下载旧key版本,然后再重定向即可. 手动引用两个版本的DLL错误的原因是我 publicKeyToken 大小写的问题(竟然没校验~~) 但我想不明白,这样搞如果依赖一多的话,甚至那 ...

  10. sql的系统关键字的概述

    create proc proc_B as SELECT * FROM [ZkbTest].[dbo].[T_ZKB] exec sp_helptext proc_B select * from sy ...