JavaScript-Javascript 函数的执行过程问题?
这段代码为什么会输出的顺序为什么会是这样,有人能讲解一下原理吗?
a();
function a(){
alert(2);
}
a();
function a(){
alert(1);
}
a();
var a = function() {
alert(3)
}
a();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
执行过程应该是:1,1,1,3
测试环境:Chrome、FireFox、IE
为了方便,从上到下,将四个
a()
,分别描述成a1
,a2
,a3
,a4
:预编译伪代码如下:
var a = undefined;//先将变量a定义成undefined
function a() {//两个函数定义预编译,两个函数同名,因此后面替换前面函数。
alert(1);
}
a1();//第一个调用
a2();//第二个调用
a3();//第三个调用
a = function(){//给变量a赋值
alert(3);
}
a4();//第四个调用
1, 在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。
2, 在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)
答案来源于网络
IE下执行顺序为:
1,1,1,3
function 方法应为最后一个被复写的函数被加载,而var作为一个变量则最后被加载.
这个变量之后被调用时,才会被解析
测了一下你的代码,发现执行第一步就报错了,不知道你用的浏览器是什么?你所说的执行结果出现了3,2,1,3,是不是你在前面就定义了函数 function a(){alert(3);} ?,看了一下我这边的环境,是因为前面定义了一个a变量,所以报错。
弄了一个纯净的环境,执行结果1,1,1,3 ,这就不难理解了,js预编译后再执行代码
我来说说我对JS解析过程(并未涉及到作用域(链)等其他概念)的理解:
1、js在运行某段代码前,首先要收集该段代码中以关键字“var”声明的变量与以关键字“function”声明的函数;要注意的是,在此阶段,js解释器并不会对变量进行初始化,而只是收集该变量的标识符而已;而对于function,js解释器也对其仅仅进行声明,如果遇到同名的标识符,则按出现的顺序进行覆盖。这也就是大家所说的js预编译或预解析阶段。所以对于问题中的代码,在此阶段,js解释器或者说浏览器得到:
2、经过预编译或预解析阶段,js解释器才会自上而下地进行代码的执行。因为我们已经在预编译或预解析阶段已经对函数a进行了声明,所以:
对于js的运行,各位可以借助于firebug等js调试工具进行查看