var变量与变量提升
使用var关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶部(如果声明不在任意函数内,则被视为在全局作用域的顶部)。这就是所谓的变量提升(hoisting)
后台实际上会转化成这样
value变量的声明被提升到了顶部,而初始化工作则保留在原处。这以为着在else分支value的变量也是可访问的,此处它的值会是undefined,因为它并没有被初始化。
块级声明
块级声明也就是让所声明的变量在指定快的作用域外无法被访问。块级作用域在如下情况被创建;
1 在一个函数内部
2 在一个代码块(由一对花括号包裹)内部
let声明语法域var语法一致
let声明没有被提升到函数定义的顶部,这样使用会报
上面就是块级作用域的基本使用。下面会带来一点let和var特别的地方
禁止重复声明
如果一个标识符已经在代码块内部被定义,那么在此代码块内使用同一个标识符进行let声明就会导致抛出错误
上面会报错,但是var声明是不会的
不在同一级别声明变量,不会报错,这个新变量会屏蔽全局的
count变量,从而在局部阻止对于后者的访问。
常量声明
const常量,它们的值在被设置完成后就不能再被改变,所有的const变量都需要在声明试进行初始化。
对比常量声明与let声明
1 常量声明与let声明,都是块级声明。这意味着常量在声明它们的语句块外部是无法访问的,并且声明也不会被提升
2 const变量和let另一个相似的地方,也是禁止重复声明
使用const声明对象
const声明会阻止对于变量绑定与变量本身自身值的修改,这意味着const声明并不会阻止对变量成员的修改
记住:const阻止的是变量绑定的修改,而不是阻止对成员值的修改。
暂时性死区
使用let或const声明的变量,在达到声明处之前都是无法访问的,试图访问会导致一个引用错误,即使在通常是安全的操作时(例如使用typeof运算符),也是如此
块级作用域最需要使用的场景1-循环中的块级绑定
对比var let明显使用let符合我们的使用期望。
块级作用域最需要使用的场景2-循环内的函数
上述原因因为变量i在循环的每次迭代被共享了(没有块级作用域)
为了修正这个问题,开发者在循环内使用立即调用函数表达式,以便在每次迭代中强制创建变量的一个新副本
幸运的是使用let完美解决这个问题
let每次使用完,就销毁重新创建。
循环内的常量声明
在常规的for循环中,你可以初始化时使用const。但循环会在试图改变该变量的值时抛出错误。
BUT!!!!!!!!!!!!!
const变量在for-in或for-of循环中使用时,与let变量效果相同。
最后一点---全局块级绑定
let与const不同于var的另一个方面是在全局作用域上的表现。当在全局作用域上使用var时,它会创建一个新的全局变量,并成为全局对象(在浏览器中是window)的一个属性,这意味着使用var可能会无意覆盖一个已有的全局属性
然而若你在全局作用域上使用let或者const。虽然在全局作用域上会创建新的绑定,但不会有任何属性被添加到全局对象上。这也就意味着你不能使用let或const来覆盖一个全局变量,你只能将其屏蔽。
块级绑定新的最佳实践
在es6的发展阶段,被广泛认可的变量声明方式是:默认情况下应当使用let而不是var。对于多数js开发者来说,let的行为方式正式var本应有的方式,因此直接用let代替var更符合逻辑。
然而随着更多的开发者迁移到es6上,一种代替方案变得更为流行。那就是默认情况下使用const,并且只在知道变量值需要被更改的情况下才使用let。其理论依据是大部分变量在初始化之后都不应当被修改,以为预期外的改动是bug的源头之一。
总结
let 与 const 块级绑定将词法作用域引入js。这两种声明方式都不会进行提升。并且只会在声明它们的代码块内部存在。由于变量能够再必要位置被准确声明,其表现更加接近其他语言,并且能减少无心错误的产生,作为一个副作用,你不能在变量声明位置之前访问它们,即便使用的是typeof 这样的安全运算符,由于块级绑定存在暂时性死区,试图在声明位置之前访问它就会导致错误。
let与const的表现在很多情况下都相似与var ,然后在循环中就不是这样,在for-in与for-of循环中。let与const都能每一次迭代时创建一个新的绑定,这意味着在循环体内创建的函数可以使用当前迭代所绑定的循环变量值(而不是像使用var那样,统一使用循环结束时的变量值)。这一点在for循环中使用let声明时也成立,不过在for循环中使用const声明则会导致错误。
块级绑定当前的最佳实践就是:在默认情况下使用const.而只在你知道变量值需要被更改的情况下才使用let。这在代码中能够确保基本层次的不可变性,有助于防止某些类型的错误。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。