1.预解析
<script>
// 1问
//console.log(num);
//2问
console.log(num);//undefined 坑1
var num = 10;
//3问
fn();
function fn() {
console.log(11);
}
//4问 坑2
fun();//报错
var fun = function () {
console.log(22);
}
</script>
预解析相关概念
JavaScript代码是由浏览器中的JavaScript解析器来执行的。
JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。
-
预解析在当前作用域下,JS代码执行之前,浏览器会默认把带有 var 和 function声明的变量在内存中进行提前声明或定义。
-
代码执行从上往下执行JS语句
预解析会把变量和函数的声明在代码执行之前完成,预解析也叫做变量、函数提升。
1.1 变量预解析(变量提升)
变量的声明会被提升到当前作用域的最上面,变量的赋值不提升。
坑1:
<script>
console.log(num); // 结果是多少?
var num = 10; // ?
相当于
var num;
console.log(num);// 结果是 undefined
num = 10;
</script>
结果: undefined 注意: 变量提升只提升声明,不提升赋值。
坑2:
<script>
fun();//报错
var fun = function () {//fun是变量名,不是函数名
console.log(22);
}
相当于
var fun;
fun();
function () {
console.log(22);
}
</script>
结果: 报错 注意: 变量提升只提升声明,不提升赋值。
1.2 函数预解析(函数提升)
函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
<script>
fn();
function fn() {
console.log(11);
}
相当于
function fn() {
console.log(11);
}
fn();
</script>
结果: 控制台打印字符串 --- "打印" 注意: 函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!
预解析案例1:
<script>
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
//相当于执行
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun();//undefined
</script>
结果: undefined
预解析案例2:
<script>
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
//相当于
var num;
function fn() {
var num;
console.log(num);//undefined
num = 20;
console.log(num);//20
}
num = 10;
fn();
</script>
结果: undefined 20
预解析案例3:
<script>
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
//相当于
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);//undefined
console.log(b);//9
a = '123';
}
a = 18;
f1();
</script>
预解析案例4:
<script>
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
//相当于
function f1() {
var a;
a = 9;
b = 9;
c = 9;
console.log(a);//9
console.log(b);//9 未声明,当全局变量看
console.log(c);//9 未声明,当全局变量看
}
f1();
console.log(c);//9
console.log(b);//9
console.log(a);//a是局部变量 报错
</script>
结果:9
9
9
9
9
注:var a=b=c=9; 只声明了a;局部变量未声明按全局变量看