JS ES6 变量声明 - junruchen/junruchen.github.io GitHub Wiki

所有变量声明的方式:

  • 最常见变量声明:var function
  • 全局变量,如 a=2, 若未声明变量a, 则会直接创建在全局变量中;
  • 在创建函数时,会默认声明函数参数
  • ES6中新增的声明方式:letconstimportcalss

varconst let的主要区别

1、变量提升问题

  • var声明的变量存在变量提升
  • letconst声明的变量不存在变量提升,但存在暂时性死区

在预编译阶段,JavaScript引擎扫描代码时,遇到变量声明,会把var声明提到作用域的顶端,而let const声明,则会被放在暂时性死区中。

访问暂时性死区中的变量,会触发运行时错误,只有执行变量声明语句后,变量才会从暂时性死区中移除,才可正常访问。

2、重复定义问题

  • var声明的变量可以重复定义
  • letconst声明的变量在用一作用域下不可重复声明

3、全局变量问题

  • var声明的变量可能会覆盖全局变量
  • letconst声明的变量只可能会遮蔽全局变量,不会覆盖全局变量,即不会破坏全局作用域

4、作用域问题

  • 在ES6之前,只存在全局作用域函数作用域

    • 使用var声明变量,可能会出现内部变量覆盖外部变量的情况
    • 使用var声明变量,循环变量会泄漏为全局变量
    • ES5规定函数声明只能在全局作用域或者函数作用域中进行,但浏览器为了兼容旧代码,不会报错
  • ES6中,除了全局作用域、函数作用域,引入了块级作用域的概念,如{}, if{} for(){}都会形成块级作用域:

    • 使用letconst声明变量时,循环变量不会泄漏成为全局变量。在for循环中,设置循环变量与循环体内部是两个单独的作用域。
    • 可以在块级作用域中进行函数声明,需要注意的是,块级作用域必须存在{}
    • 规定块级作用域中:
      • 严格模式下,函数声明语句的行为类似于let,在块级作用域之外不可引用,且会被提升至块级作用域的顶部。如果是let定义的函数表达式,不会被提示。
      • 非严格模式下,为了兼容旧代码,最终的函数声明语句的行为类似var, 声明会被提升到外围函数或全局作用域的顶部,而不是代码块的顶部。

letconst的主要区别

const声明的是常量,在声明后,常量指向的内存地址中保存的数据不可改动。所以:

  • 对于简单类型的数据,如数值、字符串等,声明后不可在修改;
  • 对于引用类型的数据,只要保持指针不变即可。