变量提升和函数提升
为什么会提升?
说起变量函数的提升,就要说一下预解析问题,谈预解析前还要说一下JavaScript这个语言的类型--------解释型语言。
什么是解释型语言呢?解释型语言就是不在服务器环境下进行编译。只有在执行脚本时也就是运行程序的时候才会进行翻译,每段代码进行执行时都有解释器来解释程序代码
每执行一次解释一次。需要把JavaScript语言翻译成机器能识别的机器语言,又没有编译过程,那么就只剩下解释器解释程序代码了。这么一看效率就比较低下,相比于编译型
语言在程序执行前就编译成机器语言了,执行程序就直接使用编译过后的机器语言就可以了。速度就快一些。
我认为 变量声明函数声明都是要在内存中开辟空间的,所以为了提升解释效率就提前把这些需要开辟内存的语句进行了声明提前。目的应该就是要提升解析速度吧。
开始说预解析了,在声明函数或者变量时 ,声明变量并没有什么说的标准的 var a = xxx 就可以啦 声明函数时一定记住是要函数的声明而不是函数表达式区别在于哪里
函数声明 是这种写法 function fn(){};函数表达式 var fn = function(){};是这种写法,不难看出函数表达式就是把一个函数赋值给一个变量了。function fn(){};以及
var a = x;这两种写法都会出现声明提前,为什么会提前呢 ,当然就是预解析做的事情。预解析看到function开头或者var开头的语句就会把这个语句提前。function开头的语句
把整个语句提前,而var开头的语句把var a 这一步声明提前 a = xxx 这个赋值语句还是处于原先位置。前提是啊一定要function var作为语句的开头部分。 (function fn(){})这样的
语句就不算是function开头的语句就会被预解析忽略掉。
这种提升会带来哪些效果。
如果你在定义变量之前使用了这个变量。并不会报错而是会告诉变量是undefined的 ,如果在函数声明前调用函数,是可以进行调用的。并没有任何问题。
变量的提示我认为比较简单没什么需要提出的,函数的声明会导致很多事情发生。比如立即执行函数。立即执行函数因为函数声明会提升。如果写成function fn(){}()
这种企图在函数声明完成后立即调用,当然是不会执行的因为预解析过程就把函数声明提升上去了,假想下 这段函数声明提升后,那么原地就只剩下了一个(),当然是无法调用的
所以解决这种立即调用的问题就可以不让function作为一行语句的开头(function(){{})()或者(function(){}())这两种效果是完全一样的目的就是不让function作为语句开头,这两种方式也是最为常见的吧。
在if语句中 如果通过if判断根据判断结果声明一个函数,一定要使用函数表达式而不可以使用函数生的方式,因为函数声明会提前,还未经过判断所声明的函数就全部提前了,
肯定是达不到想要的效果,还很容易出错
如果函数声明的函数名与变量名冲突会怎么样?
fn();//1
function fn() {
console.log(1);
}
var fn = 10;
console.log(fn);//10
这里我们就可以看出来,函数声明和变量声明提前时,函数声明要优先于变量声明。fn是一个函数。在之后的赋值语句中,我们就不难理解,fn对函数的引用被切断了。
变成了一个数字了,fn就失去了对函数的引用,打印出来自然是一个数字10;
总之理解好函数提升和变量提升可以减少很多不必要的bug出现。