前言在前端面试时,Javascript的面试是必不可少的,之前看到一道关于Javascript预解析相关的面试题目,觉得很有意义,就在这里讲解一下,大家认真看下,没准在你面试的时候就遇到了呢。
Javascript
主要知识点在讲解下面的题目之前,我们先说下文章中涉及的主要知识点,掌握了下面的知识点后,看了文章中的题目就清楚了。
变量提升,在JavaScript中定义的变量声明会提前到函数顶部。
函数声明优先级大于变量声明。
函数表达式不会产生变量提升。
题目1记住上面的知识点后,我们先来看题目1。
题目1
我们一步步分析会得出什么样的结果。
在第三行中定义了var a=3,同时又在下面声明了一个函数a,两者都会进行变量提升,由于函数声明会优于变量声明,因此a实际定义为一个函数function,所以第一行代码会输出function a(){alert(10)}。
接下来在第二行,执行了a函数,输出10。
第三行代码,又对a执行了赋值操作,这时a不再是一个函数,而是数字值3,因此在第7行代码中会输出3。
在第八行代码中又对a值进行了修改,为数字6,在第九行中进行调用,但是此时a已经不指向函数,此时再执行a方法,会报错。
所以上面题目的整体结果如下图所示。
题目1结果
题目2接下来我们对题目1稍作改动,将其中的函数声明变成函数表达式类型,得到题目2,代码如下所示。
题目2
按照之前的理论,只有函数声明才可以进行变量提升,而函数表达式不能进行变量提升。
所以题目2中,只有var a = 3;才进行了变量提升,在执行第一行代码时,实际a只进行了声明,并未赋值,因此会输出undefined。
在执行第二行代码时,由于a为undefined,再调用a()方法,会报错。
因此题目2的结果如下图所示。
题目2结果
题目3题目3的代码比较简单,如下所示。
题目3
在执行aa方法后,在函数中会输出a的值,由于变量提升只会发生在函数内部,因此a变量的声明会提到aa方法的顶部,然后执行输出,又由于作用域的限制,会优先输出函数内部的变量a,而此时a还未赋值,因此输出undefined。
题目4题目4的代码如下所示。
题目4
题目4中,会首先调用aa(5);传入一个参数5,此时执行到函数内部,虽然也会产生变量提升,但是其优先级要低于传递的参数,因此a会优先赋值为5,所以会先输出5。
在外面的输出语句中,因为作用域的问题,只能访问到外部的全局变量a=0,因此会输出0。
所以题目4的结果是输出5,0。
题目5题目5的代码如下所示。
题目5
题目5相比于题目4,只是去掉了aa方法中的var a=3;前面的var。
在aa方法中虽然对a的值进行了修改,但实际是修改了函数传递的参数a,而不是外面全局变量a,因此对实际输出并没有影响。
题目5的结果输出5,0。
题目6题目6代码如下所示。
题目6
题目6中,在执行aa()方法时,传入了一个参数a,但是参数的优先级会高于变量声明的优先级,所以虽然产生了变量提升,但是会通过参数优先赋值,因此首先a=5,第一个输出为5。
然后执行代码a=3,修改a的值,在第二个输出时,就输出3。
题目6的结果是5,3。
题目7题目7代码如下所示。
题目7
题目7中,定义了一个函数aa,接收一个参数,但是在调用时并未传入参数,因此在执行第一个输出时,a未定义,因此输出undefined。
需要注意的是,在aa方法中并没有变量提升操作,因为a只是形参而已。
然后a=3,修改的也是形参a的值,在第二个输出时,输出的实际是形参a的值。
最后一行语句输出a时,输出的是全局变量a的值,虽然在aa方法中有修改a的值,但是实际修改的是形参的值,不是全局变量a的值,因此全局变量a的值并没有发生变化,最后输出0。
题目7的结果是undefined,3,0。
结束语今天文章中的所有题目都讲解完毕了,大家都掌握了吗?如果上面的题目都会做的话,应该对JavaScript预解析,变量提升等概念掌握的差不多了。