let_var_constv变量声明

变量声明之var,let,const

在ES6之前的版本中,只有var用来声明变量,let和const是ES6中加入进来的,学习这三个,先从

1.作用域开始:

  • var可以声明在函数作用域和全局作用域中,函数作用域中就是局部变量,但是在全局中声明的时候,有些不一样,看下图

    由此可以看出var在全局声明的变量都绑定到window上了,其副作用便是会覆盖全局的属性。同时由于configurable为false,所以该变量不能通过delete将其从window上删除掉。

  • 在ES6中新增加了块级作用域,而let和const生命的代码都在当前代码块中,var声明的变量则要么在全局要么在函数作用域中。

2.重复声明

  • var定义的变量重复声明不会报错,只会覆盖掉前面声明的相同变量。但是用let和const声明的变量不能再重复声明(即使是var声明过的变量),并且const声明的同时必须初始化

3.临时性死区

  • 在var定义的变量之前访问该变量返回undefined,因为js先解析后执行,解析的时候会声明var定义的变量和函数声明。但是用let和const声明的变量在声明之前会报错,即使是使用typeof操作符。

4.在for循环中

  • 在for循环中若用var声明变量,则如下图所示:

    可以看出返回了5个5.
    其原因就是当我们在for循环中使用var时,var定义的变量i在全局作用域中,for循环结束arr数组压入的函数中对i的引用是循环之后的i的值。
    当我们执行arr数组中的函数时,其通过作用域链向上查找,找到的是for循环之后的值。因此这种特性也可以称之为闭包。
  • 在for循环中若用let声明变量,则如下图所示:

    可以发现使用let的时候和前面用var声明的变量结果完全不同。
    其原因便是let声明的变量在块级作用域中,在for循环体内时会创建一个和let声明的变量同名的副本并将其初始化为let声明的变量的值。因此当我们调用数组中的函数时,每个函数保存的i的值各不相同。
  • 但是const不能用在循环中,因为const代表的为不变的值,在for循环中,我们每次迭代i的值让i的值变化了。

5.在for..in和for…of循环中

  • 其和for循环中的特性基本一致,唯一的一个不同点就是,const可以在其中使用。其原因就是在for..in和for..of循环中每次迭代并不会修改它的值,而是创建一个新的绑定。但是有一点需要注意的是:我们在循环体内不能修改const定义的值。

总结实践:个人认为在大多数情况下我们可以使用const声明变量,只有在需要变量的值改变时再用let。尽量避免var的使用。

-->