JavaScript变量提升五道题,你都做对了吗?!

1,889 阅读5分钟

变量提升:在当前作用域下,会把带var和function进行提前声明或定义

注意:块级作用域只对let/const/function有效,对var无效

开始看题吧

变量提升块级作用域面试题目一

var a = 0
if(true){
    console.log(a)
    a = 1
    console.log(a)
    function a (){}
    console.log(a)
    a = 21
    console.log(a)
}
console.log(a)

打印结果

ƒ a(){}
1
1
21
1

分析

//变量提升var a , function a 
console.log(a)//undefined
var a = 0
if(true){
    console.log(a)//function a 
    a = 1
    console.log(a)//1
    function a (){}//把a之前的变化,映射全局a=1
    console.log(a)//1
    a = 21//私有,未映射到全局
    console.log(a)//21
}
console.log(a)//1

函数中包含形参的题目二

//包含形参
var a10,b=11,c=12;
console.log(test)
function test(a){
    a1
    var b =2
    c=3
}
test(5)
console.log(a)
console.log(b)
console.log(c)

打印结果

ƒ test(a){
    a= 1
    var b =2
    c=3
}
10
11
3

分析

//变量提升:var a ,function test(){}
var a10,b=11,c=12;
console.log(test)//没有块级作用域,声明并定义
function test(a){
    a1 //传入的形参为私有变量,不会影响公有
    var b =2//var声明function的私有变量
    c=3//没有var,全局
}
test(5)
console.log(a)
console.log(b)
console.log(c)

变量提升私有作用域题目三

var n = 0
function a() {
    var n = 10
    function b() {
        n++
        console.log(n)
    }
    b()
    return b
}
var c = a()
c()
console.log(n)

打印结果

11
12
0

分析

//变量提升
//var n ; var c ; function a (){}

var n = 0
function a() {
    //私有作用域, var n ,function b(){}
    var n = 10
    function b() {
        n++ //操作自己上级的作用域,不操作全局
        console.log(n)
    }
    b()
    return b
}
var c = a()
c()//相当于调用b函数
console.log(n)//全局变量不受影响,function a操作的是`var n = 10`这里的私有变量

变量提升之私有作用域易错题四

var foo = 1
function bar (){
    if(!foo){
        var foo = 10
    }
    console.log(foo)
}
bar()

// 打印结果
//10

分析: 变量提升 var foo ; function bar (){} bar()私有作用域内:变量提升 var foo,此时的foo为undefined,!foo为true,符合条件 foo = 10 ,结果打印 10

变量提升之没有var题五

console.log(a)
a = 12
function fn(){
    console.log(a)
    a = 13
}
fn()
console.log(a)

结果报错:a is not defined

Tips:变量提升之新旧浏览器差异

注意新旧版本对块级作用域下的function的处理方式不同(无论块级作用域的条件是否成立,只有有大括号{},就存在块级作用域)

  • 新版本:只提前声明function,不进行定义
  • 旧版本:提前声明并定义

例子:

console.log(a)
var a = 0
if(true){
    console.log(a)
    function a(){}
    console.log(a)
}
console.log(a)

新版本分析

  1. 变量提升 var a ,function a
  2. console.log(a) 打印a,此时a只声明,未定义,为undefined 在这里插入图片描述
  3. var a = 0给变量a赋值,a=0 在这里插入图片描述
  4. 一旦进入块级作用域,function a(){}不会给a重新赋值,但是为了兼容旧版本,会把修改过的a映射到全局,此时全局的a就是一个函数 在这里插入图片描述 在这里插入图片描述
  5. 所以打印的三个结果都是function a(){} 在这里插入图片描述

新版本谷歌打印结果 在这里插入图片描述 新版本IE11打印结果 在这里插入图片描述

旧版本分析

变量提升:var a , function a (){}

  1. 由于旧版本无视块级作用域,所以会对function进行变量提升并定义,此时获得的a就是function
  2. 定义了a变量值为0,那么a =0
  3. 进入块级作用域,旧版本无视,所以打印a依然是0,function a(){}已经声明定义过,不再执行,打印a,依然为a=0,全局还是a=0
console.log(a)//第1步
var a = 0//第2步
if(true){
    console.log(a)
    function a(){}
    console.log(a)
}
console.log(a)

IE10及以下打印结果 在这里插入图片描述

总结

只有新浏览器可以识别块级作用域,所以为了兼容旧浏览器,会采取先声明的方式,但是新浏览器不会进行定义,只有进入该函数所在的块级作用域才会进行定义。

小编:以上题目都对的话,证明变量提升的基础很强啦啦,没有做对的话建议自己再复习一下。欢迎勘误,不胜感激,有用的话点赞关注哦!

扫描二维码关注我们!
扫描二维码关注我们!

本文使用 mdnice 排版