Js变量提升与函数提升

597 阅读2分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

我们先来看一道经典的面试题,有如下代码,请问输出多少?

var a = 1
function fn(){
    console.log(a)
    var a = 2
}
fn()

这道题的正确答案是undefined,其实这道题主要考察了作用域与变量提升2个知识点,那么什么是变量提升呢?

变量提升

通过var关键字声明的变量,在声明前就可以访问到,只不过该变量的值是undefined。

那么我们如何理解这句话呢?还是以上面的面试题为例,上面的写法实际上在被JS引擎执行时,是按照下面的写法去执行的

var a= 3
function fn(){
    var a  //undefined
    console.log(a)
    a = 4
}
fn()

在fn函数内打印变量a,首先会在函数fn自身中查找有没有变量a,发现有变量a,只不过这时候变量a还没被复制是undefined,所以直接输出了undefined

函数提升

在Js中,除了变量会有提升外,函数也可以提升,注意观察下面的代码

fn() // fn函数
function fn(){
    console.log('fn函数')
}

我们可以看到,fn函数在声明前就被调用了,但是依然可以输出正确的结果。

注意:
在Js中,我们声明函数有两种方法

  • 函数声明 function fn(){...}
  • 函数表达式 var fn = function(){...} 这两种声明函数的方法,只有第一中函数声明方式会有函数提升。我们看下面的代码
fn1() // fn1函数
function fn1(){
    console.log('fn1函数')
}
fn2() // 报错,fn2 is not a function 
var fn2 = function(){
    console.log('fn2函数')
}

fn1正常调用,是因为用函数声明的方式声明fn1函数,存在函数提升
fn2报错,var fn2 = function(){...},首先fn2是一个变量,虽然他的值是一个函数,但首先他是用var声明的一个变量,由于变量提升,所以fn2是undefined,调用的时候必然报错

优先级

既然变量和函数都存在提升,那么谁的优先级更高一些呢?答案是函数提升的优先级更高

console.log(a) // Function

var a
function a() {
    console.log('a函数')
}

同时声明了变量a和函数a,第一行输出的是Function,由此可以见,函数提升要优先于变量提升

结尾

不要小看Js中的每个小知识点,稍不注意就有可能翻车。
也终于在11月的最后一天完成第7天的更文挑战,加油加油吧,共勉!