昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的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>

最新文章

  1. Ajax深入学习
  2. [Asp.net mvc]jquery.form.js无刷新上传
  3. Mono for Android 篇二 使用Spinner 实现下拉列表读取Browser.BookmarksUri
  4. install ios开发环境
  5. 典型用户 persona
  6. Android模拟器使用教程
  7. Thrift框架介绍
  8. hdu1533解题报告
  9. 杭州电 1052 Tian Ji -- The Horse Racing(贪婪)
  10. BI—脚不一样的感觉
  11. One-Based Arithmetic
  12. [Python学习] Django 权限控制
  13. Mysql大数据备份和增量备份及还原
  14. C++对象模型的那些事儿之六:成员函数调用方式
  15. 第一份offer
  16. STM32F103VET6 ADC采集64点做FFT变换
  17. 快速构建springmvc+spring+swagger2环境
  18. Python3学习之路~5.5 sys模块
  19. Python底层库的函数中from __future__ import absolute_import的作用
  20. 【原】Solr入门之概念和安装

热门文章

  1. python 通用 修饰器
  2. java学习中的一些疑惑解答
  3. tomcat:域名指向项目名
  4. SQL Server2008附加数据库之后显示为只读时解决方法
  5. Fedora17安装MySQL及配置
  6. react-native 环境搭建以及项目创建打包
  7. Redis 数据类型及其特点
  8. 系统监控工具 Tsar
  9. 剑指Offer面试题:31.两个链表的第一个公共节点
  10. 探索c#之跳跃表(SkipList)