1.预解析含义
- 在代码执行之前把变量和函数会提前解析到当前作用域的最前面
- 代码从上往下执行,代码执行之前会预解析
- 变量:带有声明的变量,只定义不赋值
- 函数:带有名字的函数,只定义不调用
2.变量预解析
例1:
//预解析是先从自身作用域中找,num声明了但是未赋值,所以打印出来是undefined
console.log(num)
var num=123
var n=1
例2:
/*
解析过程:var n
*/
var n=3
function fn(){
/*
解析过程:var n
*/
console.log(n)//从自身作用域找,此时只解读了声明的变量还未赋值,所以是undefined
var n=6
}
fn()
总结:
- 变量在未声明即被访问时会报语法错误
- 变量在声明之前被访问,变量的值为undefined
- let声明的变量不存在变量提升,推荐使用let
- 变量替身出现在相同作用域中
- 实际开发中推荐先声明再访问变量
3.函数预解析
例1:
/*
函数预解析过程:只定义函数,不调用函数
function fn(){
console.log(123)
}
function fn(){
console.log(456)
}
*/
fn()//调用函数,此时已经预先定义了直接打印即可
function fn(){
console.log(123)
}
function fn(){
console.log(456)
}
// 此函数边定义边调用
(function (){
console.log('aaa')
})
例2:
/*
函数预解析过程:定义函数
function fn(){
f1()
function f1(){
console.log('aaa')
}
}
*/
fn()//提前定义好了函数,调用即可,函数调用会开辟一个内存空间
function fn(){
/*
局部内进行预解析:只定义函数
function f1(){
console.log('aaa')
}
*/
f1()
function f1(){
console.log('aaa')
}
}
总结:
- 函数预解析(提升)与变量提升类似,是指函数再声明之前即可被调用
- 函数提升能够是函数的声明调用更灵活
- 函数表达式不存在变量提升现象
- 函数提升出现在相同作用域中
3.1函数表达式
// 函数表达式不存在函数预解析(函数提升),因为将函数赋值给一个变量了
// 只会对变量进行预解析
let fn=function (){
console.log(123)
}
概括为: 只要是匿名函数都不能进行预解析
4.let是否可以预解析
例子:
fn()
function fn(){
console.log(m)
asddd
asss
abc
let m=123
}
结果:
结论:let可以预解析
报错结果为初始化前无法访问m,说明已预解析到m
但是在为变量赋值之前的代码是不能执行的,此段代码称为暂时性死区
5.预解析案例
例子1:
/*预解析过程:
function a(){
console.log(123)
}
var a
a=函数
a=1
*/
console.log(a)
function a(){
console.log(123)
}
var a=1
console.log(a)
执行结果:
结论:预解析时函数名和变量名相同时,函数要优于变量
consloe.log(a)中的a是先预解析也就是定义函数a、打印函数a
a=1打印1
例子2:
/*
预解析执行过程:
1.定义函数:
function f1(){
var a=b=c=9
console.log(a)
console.log(b)
console.log(c)
}
2.调用函数时,函数会开辟一个内存空间
var a=9;b=9;c=9
打印即可:9、9、9
3.函数执行完打印c、b、a
其中c、b、是全局变量在函数中已经预解析了a是局部变量,不可全局使用,会报错显示a为未定义
*/
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)
}
打印结果