1.我们js引擎运行js 分为两步,1.预解析,2.执行代码
(1)预解析:js引擎会把js里面所有的var还有function提升到当前作用域发的前面
(2)执行代码:按照代码书写的顺序从上往下执行
2.预解析分为 变量预解析(变量提升)和 函数预解析(函数提升)
(1)变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提示赋值操作。
这里在var num = 10;之前进行console.log(num);之所以能输出undefined而不报错是因为js进行了预解析,把var num;操作提到了该作用域的最前面,但是没有把赋值提前,所以运行到console.log(num)时,num变量已经存在但没有进行赋值操作,所以输出undefined而不报错。
这里在前面直接调用fun(),运行结果是报错了,是因为这里的fun是个变量,不是函数,所以提升是把var fun;被提升到前面后(未进行赋值,也就是未进行函数定义),进行fun(),此时fun()函数未被定义,所以调用fun肯定会直接报错。
(函数表达式 调用必须写在函数表达式的下面)
2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
而这里的function fn(){xxx}是函数声明,会被提升到当前作用域的最前面,所以fn()放在前面也能正常运行。
例子:手写出下列案例实际运行效果的代码
=》
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num=10;
fun();
提升之后代码一眼清晰,根据作用域链看console.log(num)上面这个var num就知道输出的是undefined。
=》
var num;
function fn() {
var num;
console.log(num);
num=20;
console.log(num);
}
num=10;
fn();
输出结果是undefined和20。
=》
function f1() {
var a;
a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
结果是 99999+报错
因为f1函数体中只有a进行了变量声明,b和c进行了赋值没有进行变量声明,所以是b,c作为全局变量,a是函数体内的局部变量。