三大门派var,const,let之间的纠纷

三大门派var,const,let之间的纠纷

let,const是属于块级作用域的,而var是属于全局作用域的

对于这三大门派,我们可以从以下四点进行分析学习

  • 作用域规则
  • 重复声明/重复赋值
  • 变量提升(hoisted)
  • 暂时死区(TDZ)

var的缺陷是什么?

  1. var 存在变量提升,那么接下来的这段会发生什么?
    function fun2(){
        let f3 = 3
        const f4 = 4
        //Uncaught ReferenceError: Cannot access 'f1' before initialization
        //console.log('f1--',f1)
        console.log('f2--',f2)
        //undefined
        console.log('f3--',f3)
        //3
        console.log('f4--',f4)
        //4
       //Uncaught ReferenceError: Cannot access 'f5' before initialization
        //console.log('f5--',f5)
        let f1 = 1
        var f2 = 2
        const f5 = 5

    }
    fun2()
  1. 该销毁的没有销毁,没有屏蔽功能

    因为var声明的变量存在全局变量中,存在变量提升问题,而且var声明的变量没有销毁,所以不能实现块级作用域变量销毁的概念,但是let,const的出现解决了这个问题。

    function fun1(){
        for(var i =0 ;i<5;i++){

        }
        //i-- 5
        console.log('i--',i)
        for(let j =0 ;i<5;i++){

        }
        //Uncaught ReferenceError: j is not defined
        console.log('j--',j)
    }
    fun1()
  1. 变量容易在不被察觉的情况下被覆盖掉

        var myname = "w"
        function showName(){
            console.log('before--',myname);
            if(0){
                var myname = "j"
            }
            console.log('after--',myname);
        }
        showName()
       
    
  2. 所有未声明直接赋值的变量都会自动挂在顶层对象下,造成全局环境变量不可控、混乱

        var a = 0
    
        function fun(){
            //重新赋值,对于let,const
            a = 10
            b = 11
            console.log('fun--a',a)//10
            console.log('fun--b',window.b)//11
        }
    
  3. 允许多次声明同一变量而不报错,造成代码不容易维护,直接修改变量值

    var t = 100
    function fun3(){
        for (let i  = 0;i<10;i++){
            t = i
            console.log('fun3--i--',t)
        }
    }
    
    var arr = [];
    for (var i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i);
        };
    }
    //10
    arr[6]();
    

let 解决了var的什么缺陷

1不存在变量提升,有暂时死区,始终在

在 JavaScript 中,当控制流进入它们出现的范围时,所有绑定声明都会被实例化。传统的 varfunction 声明允许在实际声明之前访问那些绑定,并且其值(value)为 undefined 。这种遗留行为被称为变量提升(hoisting)。当控制流进入它们出现的范围时,letconst 声明也会被实例化,但在运行到实际声明之前禁止访问。这称为暂时性死区( Temporal Dead Zone)。TDZ 的存在是为了防止传统提升可能造成的那种错误。

//Cannot access 'test1' before initialization
//console.log(test1)
let test1 = 'test1'
{
    //test2 is not defined
    //console.log(test2)
    let test1 = 'test2'
}
let myname = "w"
function showName(){
    //before-- w
    console.log('before--',myname);
    if(0){
        let myname = "j"
    }
    //after-- w
    console.log('after--',myname);
}
showName()
  1. 不允许同一块重复声明

    在一个嵌套作用域中声明同一个变量名称的行为称做 屏蔽

function sumArr(arrList) {
  let sum = 0;
  for (let i = 0; i < arrList.length; i++) {
    var arr = arrList[i];
    for (let i = 0; i < arr.length; i++) {
      sum += arr[i];
    }
  }

  return sum;
}
  1. 使用 let 在全局作用域下声明的变量也不是顶层对象的属性

    属于块级作用域,作用域块内声明的变量不影响块外面的变量

    块作用域变量在包含它们的块或 for 循环之外是不能访问的

    var arr = [];
    for (let i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i);
        };
    }
    //6
    arr[6]();
    
    function fun4(){
        let g = 44
        var gg = 55
    }
    //Uncaught ReferenceError: g is not defined
    console.log('g',g)
    console.log('gg',gg)
    

const 解决了var的什么缺陷

  1. const 声明一个只读的常量。一旦声明,常量的值就不能改变。

  2. 其它 constlet 相同,例如:

    • 常量也是不提升,同样存在暂时性死区
    • 作用域相同,只在声明所在的块级作用域内有效

var VS let VS const

varletconst 的不同主要有以下几个方面:

  • 作用域规则
  • 重复声明/重复赋值
  • 变量提升(hoisted)
  • 暂时死区(TDZ)

作用域规则

let/const 声明的变量属于块作用域,只能在其块或子块中可用。而 var 声明的变量的作用域是是全局或者整个封闭函数

重复声明/重复赋值

  • var 可以重复声明和重复赋值
  • let 仅允许重复赋值,但不能重复声明
  • const 既不可以重复赋值,但不能重复声明

变量提升(hoisted)

var` 声明的变量存在变量提升,即可以在变量声明前访问变量,值为`undefined
let` 和 `const` 不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错 `ReferenceError

暂时死区(TDZ)

var不存在暂时性死区, letconst存在暂时性死区,只有变量声明后,才能被访问或使用

本文参考:三分钟学前端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值