带var和不带的区别

156 阅读2分钟

看代码输出结果并小结

   /*
   全局作用域(栈内存)
   1. 变量提升
       var a;
   2. 代码执行
   */
   console.log(a) // => undefined
   var a = 12
   a = 13
   console.log(a) // => 13
    /*
   全局作用域(栈内存)
   1. 变量提升
   2. 代码执行
   */
   console.log(a) 
   // => Uncaught ReferenceError: Cannot access 'a' before initialization
   // => 在JS中,上一行代码报错,便不再执行下一行   
   let a = 12
   a = 13
   console.log(a) // => 13

小结: var存在变量提升,let不存在变量提升,更严谨些

   //=> 在全局作用域下的区别
   /*
   不带var的: 相当于给全局变量window设置了一个属性a
   window.a =  15
   */ 
   a = 15 
   console.log(a) // => window.a
   //=> 在全局作用域下的区别
   /*
   带var的: 在全局作用域下声明了一个变量b(全局变量),同时给window添加了一个属性(只有全局作用域具备这个特点)
   */ 
   var b = 15 //=>创建变量b & 给window设置了属性b
   console.log(b) //=>15
   console.log(window.b) //=>15

小结: 在全局作用域下,不管带不带var,都给全局对象window设置对应属性 除此之外,带var的还在全局作用域下声明了全局变量

let/const和var的区别

  1. let和const不存在变量提升
    创建变量的六种方式中,var/function有变量提升,let/const/class/import都不存在这个机制

  2. 相同作用域下,var允许重复声明,而let不允许
    在相同作用域中(或执行上下文中)
    如果使用var/function关键字重复声明变量,不会有影响(声明一次后,再遇到就不会重复声明了)
    但是使用let/const就不可以,浏览器会校验当前作用域中是否已经存在这个变量,如果已经存在了,则再次基于let等重新声明就会报错

  3. let能解决typeof检测时出现的暂时性死区问题

   console.log(a)  //=>Uncaught ReferenceError: a is not defined
    console.log(typeof a) 
    //=>"undefined" 这是浏览器BUG,本应该报错因为没有a(暂时性死区)
    console.log(typeof a) 
    //=>Uncaught ReferenceError: Cannot access 'a' before initialization
    let a
  1. let有块级作用域