目录
提升的定义
无论作用域中的声明出现在什么地方,都将在代码被执行前先进行处理,将所有的声明移动到各自作用域的顶端,这个过程叫提升。
变量提升
a=2;
var a;
console.log(a);
这段代码console会打印什么呢?也许是undefined,但其实会打印 2 。因为这段代码实际会被这样处理:
var a;
a=2;
console.log(a);
其中:var a;是编译,后面的两句才是执行。
再来看一段:
console.log(a);
var a=2;
它会被处理成这个样子
var a;
console.log(a);
a=2;
同样的 var a;是编译,后面两句是执行,因为a=2赋值是在打印之后,所以这段代码会输出 undefined.。
从上面两段代码就可以知道 以var这样声明的变量,放到哪里都会在编译阶段被移动到当前作用域的最上面。
函数提升
函数的声明跟变量声明也是一样会被提升,下面看函数的实例:
hello();//执行
function hello(){//函数声明,这里可以看到声明在后,执行在前,能正常执行吗?
console.log('hello');
}
我们运行这段代码,可以看到是正常输出的,也就是函数声明被提升了。
那如果我们用var 来声明函数会怎么样呢?
hello();//执行
var hello = function (){
console.log('hello');
}
执行会报错:
为什么呢?因为 var hello = function (){
console.log('hello');
} 这样写的话var hello是变量声明,后面的是赋值操作,变量被提升了,赋值操作是没有被提升的,其实这段等同于这样:
var hello;
hello();//执行
hello = function(){
console.log('hello');
}
在执行的时候hello是只被声明的,它的值是undefined,所以用()来调用会出现TypeError,改成下面这样才能正常工作,想用这种方式写,需要将其放到函数执行的前面:
var hello= function(){
console.log('hello');
}
hello();//执行
函数优先
hello();//执行
var hello;
function hello(){
console.log('log hello');
}
hello = function(){
console.log('log hello1');
}
这段代码会打印出:log hello
从结果中可以看到函数执行的时候是打印了log hello,函数执行完以后hello变量会被赋值语句替换成打印log hello1的函数,为啥?实际这段代码会被处理成这样
function hello(){
console.log('log hello');
}
hello();//执行
//var hello这句被忽略了
hello = function(){
console.log('log hello1');
}
函数优先提升到最上面,此时在用声明var hello将被忽略,因为此时已经存在hello了,他是一个函数,那接下来执行函数hello当然就打印出之前的结果,然后才被替换。
函数声明覆盖
hello();//执行
function hello(){
console.log('log hello');
}
function hello(){
console.log('log hello2');
}
function hello(){
console.log('log hello3');
}
打印的是 log hello3,后面的函数声明把前面的函数声明都覆盖了。
总结
函数声明和变量声明都会被提升到当前作用域的最上方,并且是函数优先,也就是声明语句我们在放在什么位置都可以。
但是为了代码好看、好维护、为了避免重复声明以及避免不必要的风险,还是尽量的把声明放到最前面。