关于JavaScript预编译和执行顺序以及函数引用类型的思考
昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了。问题抽象出来是这样的:
<script >
var A=fun;
function fun(){
alert(1);
}
</script>
<script>
function fun(){
alert(2);
}
A();
</script>
我希望输出2,但是运行结果是1。如果两个代码块合并为一个,那输出结果就是2。
解释这个问题,涉及到两方面的内容:[JavaScript预编译和执行顺序]、[基本类型和引用类型]。
JavaScript预编译和执行顺序
1.JavaScript的解析过程分为预编译和执行两个阶段,顺序都是从上到下。
2.解析过程分块解析。如果页面有A、B两个<script>代码块,那么浏览器解释器的执行过程是:预编译A执行A → 预编译B执行B
3.在预编译期会声明变量(仅声明未赋值)并定义函数。在执行阶段给变量赋值。
4.变量没声明就引用,会报错。声明变量需使用var。
参考http://blog.csdn.net/cxiaokai/article/details/7552653
根据以上三点,可以解释开头代码中"var A=fun;"为什么没有报错。因为预编译阶段声明了变量A并定义了函数fun,执行阶段变量fun赋值为函数A,所以不会报错。
但是,这样并不能解释为什么第二个代码块中的fun()没有把上一个代码块中的fun()覆盖掉。而如果代码最后运行fun()的话,输出的就是2。如此看来,代码运行到最后面的时候,A和fun已经不相等了。下面转换一下开头的例子:
<script >
var A=funA;
function funA(){}
</script>
<script>
function funA(){}
document.write(A===funA);
</script> <script >
var B=funB;
function funB(){}
function funB(){}
document.write(B===funB);
</script>
果然,上面代码块输出false,下面代码块输出true。这样看来应该是和变量A保存的是值还是地址有关系了。
基本类型和引用类型
1.JavaScript的变量值可以是两种情况:基本类型值和引用类型值。
基本数据类型:Undefined、Null、Boolean、Number、String;引用数据类型:Object。
2.检测是否为引用数据类型可以使用 xx instanceof Object,如果是会返回true。
先使用xx instanceof Object对上面代码段A、funA进行引用类型检测,结果都为true。说明A和funA都是引用类型。再结合上面javascript预编译和执行顺序的研究,对上面示例代码可以这么解释了:
<script >
var A=funA;
function funA(){}
//函数为引用类型,即函数名表示一个指针
//预编译期声明A并定义funA,funA指向一个内存空间。执行期,通过对A赋值,A也指向了这个内存空间。
</script>
<script>
function funA(){}
document.write(A===funA);
//这里重新定义了funA,funA指向了新的内存空间,而A指向未变。所以A!==funA。
</script> <script >
var B=funB;
function funB(){}
function funB(){}
document.write(B===funB);
//预编译期声明B并定义funB,funB指向一个内存空间,接着重新定义了funB,funB指向新的内存空间。执行期,通过对B赋值,B也指向了这个新的内存空间。所以B===funB。
</script>
后记
朋友如果耐心看完了以上的内容,不妨猜一下下面这段代码的运行结果:
<script >
function a(){
alert(b);
alert(c);
}
a();
var b=1;
c=2;
</script>
关于JavaScript预编译和执行顺序以及函数引用类型的思考的更多相关文章
- javascript的预编译和执行顺序
原文:javascript的预编译和执行顺序 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 代码一<html> ...
- JS的预编译和执行顺序 详析(及全局与局部变量)
最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题: <html> <head> <title> ...
- JS的预编译和执行顺序 详析
原文:JS的预编译和执行顺序 详析 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 复制代码 代码一 <ht ...
- JS 的预编译和执行顺序
脚本执行js引擎做的工作: 语法分析 预编译 解释执行
- JavaScript 预编译(变量提升和函数提升的原理)
本文部分内容转自https://www.cnblogs.com/CBDoctor/p/3745246.html 1.变量提升 console.log(global); // undefined var ...
- javascript预编译和执行过程总结
javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块 ...
- JS之预编译和执行顺序(全局和函数)
预编译的两种情况 全局: 1.全局 直接是script标签中的代码,不包括函数执行 执行前: 1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析 2.分析变量声明 ...
- JavaScript-深入理解JavaScript(一、预编译和执行过程)
一.预解析 JavaScript 在执行前会进行类似“预解析”的操作:首先会创建一个在当前执行环境下的活动对象, 并将那些用 var 声明的变量.定义的函数设置为活动对象的属性, 但是此时这些变量的赋 ...
- javascript运行机制之执行顺序详解(转)
转自http://www.admin10000.com/document/3385.html JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言, ...
随机推荐
- idea 根据数据库表自动创建持久化类
一.点击最右边的Database: 二.点击,再点DataSource选择数据库类型,配置数据库信息: 三.打开项目结构,选择,找到你的项目,点击,添加hibernate: 四.如果有现成的cfg.x ...
- oracle 全文检索创建脚本示例
--创建全文索引 grant execute on ctx_ddl to username;--使用其他帐号对username授权exec ctx_ddl.create_preference('my_ ...
- Centos7 Docker 多主机 容器互连--基于OVS
来一张自己画的图,mark:2016年6月27日17:09:14 自己理解,如有错误 多谢指教. centos7, 部署OVS和docker.以及基于centos6.8的ssh images 命令. ...
- 在C#中使用消息队列RabbitMQ
1.什么是RabbitMQ.详见 http://www.rabbitmq.com/. 作用就是提高系统的并发性,将一些不需要及时响应客户端且占用较多资源的操作,放入队列,再由另外一个线程,去异步处理这 ...
- JavaScript判断移动端及pc端访问不同的网站
JavaScript判断移动端及pc端访问不同的网站 现在很多网站都是分为两个版本,一个pc端的一个移动端的(响应式除外),针对这两个版本,就需要对访问的设备进行判断,如果是pc,就直接访问pc网站, ...
- 安卓动态调试七种武器之孔雀翎 – Ida Pro
安卓动态调试七种武器之孔雀翎 – Ida Pro 作者:蒸米@阿里聚安全 0x00 序 随着移动安全越来越火,各种调试工具也都层出不穷,但因为环境和需求的不同,并没有工具是万能的.另外工具是死的,人是 ...
- HTML5- Canvas入门(七)
这是本系列的最后一篇入门文章,主要是对剩余的未说明的canvas方法来逐个介绍. 首先,如果你是一名擅长矢量设计的设计师,对Illustrator或者Fireworks很熟悉的话,那你肯定知道它们有一 ...
- ReactJS入门(一)—— 初步认识React
React刚开始红的时候,由于对其不甚了解,觉得JSX的写法略非主流,故一直没打算将其应用在项目上,随着身边大神们的科普,才后知后觉是个好东西. 好在哪里呢?个人拙见,有俩点: 1. 虚拟DOM —— ...
- Lesson 13 The Greenwood Boys
Text The Greenwood Boys are group of pop singers. At present, they are visiting all parts of the cou ...
- Python黑帽编程2.6 模块
Python黑帽编程2.6 模块 我们已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个 ...