let命令
- let声明的变量只在其所在的代码块内有效
在代码块内使用let声明时,外部是无法读取到内部声明的变量的
需要特别注意的是:在for循环内,设置循环变量的那一部分为父作用域,而循环体内为一个子作用域 ,所以,上图代码会打印出10个 'abc' ,而不是 0 到 9
- 不存在变量提升,只会形成暂时性死区
当我们在一个块级作用域内使用let或const声明了一个变量,那么该变量就会绑定这个作用域。
在块级作用域内,我们声明了一个变量tmp,所以该变量会绑定在这个作用域内,不会受全局变量tmp的影响,而且,由于tpm在被赋值时还未被声明,所以会报错。同时,也造成了一个暂时性死区。
而且,当我们使用 typeof 时,若在暂时性死区内时,也会报错,所以 typeof 这个操作也不再百分百安全了。
总之,在代码块内,使用let声明变量前,该变量都是不可用的。只有当声明的哪一行被运行后,该变量才能被使用。
- 不允许重复声明
在同一个作用域内,一个变量是不能被重复声明的。
- 块级作用域
首先,我们来看一段代码
var tmp = new Date()
function f (){
console.log(tmp)
if(false){
var temp = 'hello world'
}
}
//fn() undefined
由于ES5 只有全局作用域 和 函数作用域,所以次代码等价于下面的代码,所以会造成为打印出时间日期
var tmp = new Date()
function f (){
var temp
console.log(tmp)
if(false){
temp = 'hello world'
}
}
//fn() undefined
而且,如果我们使用for循环,var声明的用来控制循环的变量,也会泄露为全局变量
for(var i = 0; i < 5; i++){
console.log('hi')
}
//console.log(i) 5
当我们使用ES6的let时,就不会出现此问题。
- 块级作用域与函数声明 在 ES5 时,函数只能在全局作用域,或者函数作用域在声明,不能在块级作用域内声明(为了兼容旧代码,并不会报错)
而且,声明的函数由于变量提升,会自动跑到 全局作用域/函数作用域 的顶部。
ES6 出现块级作用域后,在块级作用域内声明的函数类似于let,不会被外部读取到。但是由于兼容性考虑,在块级作用域内声明的函数,会首先在 函数作用域/全局作用域 顶部声明,然后在块级作用域内赋值
因此,在块级作用域内,我们应该尽量避免使用函数表达语句,而不是函数声明语句
//函数表达式
{
let fn = function(){}
}
//函数声明式
{
function fn (){}
}