变量提升
变量提升是指将变量申明提升到它所在作用域的最开始部分。
代码:
console.log(a);// undefined
var a='变量';
console.log(a);//变量
// 预解析相当于
var a;
console.log(a);
a='变量';
console.log(a);
函数提升
ES6之前,函数没有块级作用域(一对{}即是一个块级作用域),只有全局作用域和函数作用域。
函数创建有两种⽅式:1、函数声明形式;2、函数表达式。(只有函数声明形式才有函数提升),还有另外⼀种⽅式:构造函数形式:var a = new Fn(),技术⾓度来讲也是⼀个函数声明形式
console.log(fn); //f fn(){ console.log(123)}
console.log(fn()); //fn()的返回值 如果函数没有返回值,默认为:undefined
var fn=456;
function fn(){
console.log(123); //执行fn()里面的console.log 123
}
console.log(fn); // 456
fn=789;
console.log(fn); //789
console.log(fn()); //error fn is not a function
//预解析相当于
//函数提升优先级高于变量提升优先级
var fn=function fn(){
console.log(123);
}
//变量提升,变量提升不会覆盖(同名)函数提升,只有变量再次赋值时,才会被覆盖
var fn;
console.log(fn);
console.log(fn());
fn=456;//变量赋值,同名变量将同名函数覆盖掉了
console.log(fn);
fn=789;//再次赋值
console.log(fn);
console.log(fn());
优先级
函数提升优先级,高于,变量提升优先级,且不会被,同名变量声明覆盖,但是会被同名变量赋值后覆盖
拓展
(1)var fn = function(){}和function fn(){}的区别:前者为变量提升,后者为函数提升。
如果是用变量提升来声明函数,如果在此前调用该函数,此时的函数对象并没有创建,变量fn2赋值为undefined,所以浏览器不能识别,把它当做函数来调用,所以最后报错。
(2)在js中,函数是第一公民
被覆盖的不是函数fn,而是var fn =3;
<script>
var a=4;
function fn(){
console.log(a);
var a=5;
}
fn();
</script>
大家可以猜一下这个结果。
结果在最下方
。。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
结果为undefined。
预解析过程
var a;
function fn(){
var a;
console.log(a);
a=5;
}
a=4;
这里又涉及就近原则,a会先取离他最近的a的赋值