前言
半夜上QQ,发现鬼灰找我,说要我帮忙看看群里妹子朋友的代码:!: ,瞅了一眼,是JS,然后用眼睛目测了一下运行结果,发在了群里,果不其然就错了(因为菜
分析
a(); var a = function(){ console.log(1); }; a(); function a(){ console.log(2); }; a(); var a = function(){ console.log(3); }; a();
代码本身不长,但写法却是第一次见,正常情况下,我们都是先申明函数,然后再调用,而这里却是先调用再声明。
因为之前猜错了
按着提炼的关键词,我找到了相关文章,《js函数和变量的执行顺序【易错】》。
懵懵懂懂的看了一遍,大概知道了为什么执行结果是2 1 1 3。
JS的解析过程分为两个阶段:预编译期(预处理)与执行期。
此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。
也就是说在JS预处理的时候,源代码会预处理成下面这样:
function a() { alert(2); }; a(); var a = function() { alert(1); }; a(); a(); var a = function() { alert(3); }; a();
然后代码才会开始执行,这也是为什么执行结果是2 1 1 3。
插曲
我相信很多朋友都有在控制台直接运行JS的习惯,这次调试的时候,我首先使用的也是控制台,但我发现每次一执行,都会在最后打印一个undefined的值,本着去伪存真的原则,我去查找了原因(在HTML文件中直接运行则不存在最后出打印undefined值)。
① 当我们调试的时候,实质上控制台输出的是调试命令的返回值。
② 如果调试命令本身就带有日志打印的语句,则先执行命令的日志打印语句,后执行命令的返回值。
③ 如果调用函数,则返回的是函数的返回值。
④ 如果调用的表达式有很多行,则只打印最后一个分号的表达式的值。
以上结论摘自《为什么console.log()后会有一个undefined》。
说白了就是在console.log的时候没有响应的返回值,以至于在最后打印了undefined的值。
后话
本文引用的相关资料,在文中均有明确链接,本文只是记录学习过程中遇到的问题,不存在其他行为。