JS中声明变量的方式以及比较

200 阅读3分钟

声明变量

传统:var function

ES6: let const import(模块导入 import aaa from '../aa')

全面分析比较

let VS const

let 声明一个变量,变量存储的值可以修改。

let n = 12 
n = 14

const声明的变量,一旦赋值,则不能再和其他的值关联。(不允许指针重新指向)

// 具体的值是常量,不能说const声明的是常量。值是常量,声明的 都是变量。只能说指针不能重新指向。

const m = 12; m = 13  //不能修改这个值 报错

//这个代码是正确的。
const obj ={
    name:'aaa'
} 
obj.name ='bbb'

let VS var

  1. var 存在变量提升,而let不存在;

    变量提升:在当前上下文,代码执行之前,会把所有带 var(提前声明) / function(声明+定义) 关键字的进行提前的声明或者定义

  2. 全局上下文中 基于var声明变量也相当于给GO(全局对象)新增一个属性,并且任何一个发生改变,另外一个也会跟着改变(映射机制);但是基于let声明的变量,就是全局变量,和GO没有任何的关系。

     let n=12
     console.log(n)
     console.log(window.n) //undefined    对象的成员访问,没有此属性,返回就是undefined
    
     // VO(G) :n=12 <=> GO(window):window.n=12
     var n=12
     console.log(n)
     console.log(window.n) // 12
    
     n=13  // (项目中尽可能少使用不经声明的变量)相当于 window.n = 13 没有基于任何关键词的声明,则相当于给window设置一个属性  
     console.log(n) //13   首先看是否为全局变量, 如果不是,则再看为window的属性,
     console.log(m) //如果两者都不是,则报变量未定义。m is not defined 。	
    
  3. 在相同的上下文中,let不允许重复声明(无论你之前基于何种方式声明,只要声明过,则都不能基于let重复声明了)。在代码之前,浏览器会自己处理很多事情:词法分析、变量提升。 词法分析阶段:如果发现有基于let/const并且重复声明变量的操作,则直接报语法错误 Uncaught SyntaxError:Identifier '变量' has already been declared,整个代码都不会做任何的执行。 在代码执行之前,就报错,代码还没有执行,SyntaxError语法错误。

    而var很松散,重复声明也无所谓,反正浏览器也只按照声明一次处理。

  4. 暂时性死区 [浏览器暂存的bug]

    console.log(n)  // ReferenceError: 'n' is not defined
    console.log(typeof n) // undefined  基于typeof检测一个未被声明的变量,不会报错的,结果是undefined。
    
    console.log(typeof n) // 报错 ReferenceError cannot access 'n' before initialzation  不可以在声明之前使用它
                         //代码执行到这里的,报错的,也就是词法分析阶段可以通过。
    let n = 12 
    
  5. let/const/function会产生块级私有上下文,而var不会产生。

    块级作用域(块级私有上下文): 除了 对象/函数(let obj={} function fn(){})的大括号之外的其他大括号,有例如:判断体,循环体,代码块,如果存在let/const/function,则会产生块级私有上下文。