JS预解析(变量提升)
JS的正常执行顺序是从上往下依次执行,但是JS在执行之前会读取一遍JS代码
- 将所有变量声明提前(不会提升变量赋值)
- 将所有函数声明提前
接下来我们在代码的基础上来理解上面的话
1.变量预解析
console.log(a)//输出undefined
var a = 5
console.log(a)//输出5
JS在执行上述代码代码的时候,做了如下处理:
var a = undefined//此处为JS的预处理,将变量提升并且赋值为undefined
console.log(a)//输出undefined
var a = 5//此处将5赋值给a
console.log(a)//输出5
只有用var定义的变量才会进行变量提升,在ES6中,let定义变量是不会进行变量提升的
2.函数预解析
a()//输出 ’我是一个函数‘
function a(){
console.log('我是一个函数')
}
JS在执行上述代码的时候,将函数声明提前,也就是JS在预解析的时候将函数声明提前到了最顶端,这样我们可以在任何地方调用函数
如果我们通过表达式的方式创建函数,将出现下列情况:
a()//输出 a is not a function
var a = function(){
console.log('我是一个函数')
}
因为JS在做预解析的时候,将a进行了变量提升,上述代码执行情况应是如下:
var a = undefined//此时将a进行变量提升,并且赋值为undefined
a()//a在此时只是一个变量,所以当成函数进行调用会报错 “a is not a function”
var a = function(){
console.log('我是一个函数')
}
3.当变量名和函数名重复时
当函数名和变量名重复时,JS会将函数名提升的更高,就是说函数声明的优先级会更高
console.log(a)//此时输出的是函数体本身 "ƒ a(){console.log('我是一个函数')}"
var a = 10
function a(){
console.log('我是一个函数')
}
我们再看一个例子
var a = 10
function a (){
console.log('123')
}
console.log(a)//输出的a是10
上述代码函数和变量重名,函数和变量都会进行提升,函数的优先级高于变量,而在打印之前对a进行了赋值,所以打印的结果是10
console.log(a)//输出的a是函数体
var a = 10
function a (){
console.log('123')
}
上述代码函数和变量重名,函数和变量都会进行提升,函数的优先级高于变量,所以打印的结果是函数体