js中立即执行函数会预编译吗_Javascript预编译和执行过程

参考网站:

http://www.cnblogs.com/xz1367/archive/2012/01/11/2319651.html

http://blog.csdn.net/liaoxiaoli99/article/details/6387886

http://blog.163.com/i_yuhan/blog/static/1983421002012519113257934/

http://hi.baidu.com/do_itdream/item/3d75af3c9ec7cf667c034bbc

Javascript预编译和执行过程

1. 在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用

var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function

定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。

2.在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而

且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇

到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如

果在这之前使用变量,它的值会是undefined)

用var定义的变量和function定义的方法在预编译的过程中有所不同,用代码来看看:

function mm(){ }

这种形式是声明一个函数,跟 var 一个变量的机制一样,脚本在解释执行之前会做预编译处理,而

var mm = function(){ }

这种形式是对一个变量赋值,虽然也做预编译,但仅仅只是给 mm 事先变量分配一个内存空间,而没有

做初始化

window.alert(mm);

function mm(){

}

以上代码你会看到能alert出来mm的内容,但alert却是在function声明之前的,验证了脚本宿主在执行

之前对脚本做了预编译处理

window.alert(mm);

var mm = 123;

以上代码你会看到alert出一个undefined来,说明脚本宿主在执行之前对脚本做了预编译:对mm分配内

存空间但并不初始化它

window.alert(nn);

window.alert(aa);

if(true){

function mm(){ }

var aa = 1;

}else{

function nn(){ }

var aa = 2;

}

以上代码再次验证了预编译,并且说明预编译与条件无关。先弹出nn的函数定义,再弹出undefined。

上面3段代码比较容易理解,下面有些比较特殊点的

function myfunc(){

alert("hello");

}

myfunc();//这里调用myfunc,输出yeah而不是hello

function myfunc(){

alert("yeah");

}

myfunc();//这里调用myfunc,当然输出yeah

按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不

过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数

没有起到任何作用。这又是为什么呢?

原来,JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地分析执行的。而且,

在同一段程序的分析执行中,定义式的函数语句会被提取出来优先执行。函数定义执行完之后,才会按

顺序执行其他语句代码。也就是说,在第一次调用myfunc之前,第一个函数语句定义的代码逻辑,已被

第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。

如果把这个JavaScript代码分成两段,例如将它们写在一个html中,并用标签将其分成这样的

两块:

function myfunc(){

alert("hello");

}

myfunc();//这里调用myfunc,输出hello

function myfunc(){

alert("yeah");

}

myfunc();//这里调用myfunc,输出yeah

这时,输出才是各自按顺序来的,也证明了JavaScript的确是一段段地执行的。

上面是两个相同名字的function对象,如果是一个变量和一个function对象拥有相同的名字是什么情况

呢?

/*在预编译过程中func是window环境下的活动对象中的一个属性,值是一个函数,覆盖了undefined值*/

alert(func); //function func

var func = "this is a variable"

function func(){

alert("hello!")

}

上面第一行显示出来的结果是:

function func(){

alert("this is a function");

}

在预编译的情况下,它覆盖了第一个变量func

但是如果再添加两行代码,像这样:

alert(func);

var func = "this is a variable";

function func(){

alert("this is a function");

}

alert(func);

alert(func());

最后2个alert的结果又不同了,第一个alert显示的是变量func的值,第二个alert出错;

这2个结果的解释参考的网站没有给出具体的解释,其中有指明说出是在执行过程中遇到了var重新赋值

为"this is a variable",此时变量func覆盖了func方法,所以func方法已不存在。

还有一个情况,看下面的代码

alert(a);//undefined

a();//出错

var a = function(){

alert("aa");

}

a();//aa

alert(tt);//function tt(){alert('tt');}

tt();//tt

function tt(){alert('tt');}

上面的代码中根据个人理解,用var定义变量并赋值一个function方法,和用function直接定义function

方法在预编译过程中显式出不同的结果,其中用var定义的a在预编译的时候只是分配了空间但不没有赋

值,所以第一个结果为undefined,第二个方法,由于var变量a在预编译时只被声明,并未赋值,故出现

错误提示,至于tt方法,应该比较好理解了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值