「这是我参与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天的更文挑战,加油加油吧,共勉!