Let
跳到导航
跳到搜索
let 有几个特点:
1.变量不能重复声明
<script>
let name = '张三';
let name = '李四';
</script>
运行会在控制台报错 这一点和 var 不同
<script>
var name = '张三';
var name = '李四';
</script>
上面使用 var 的代码就可以正常运行。
2.块级作用域 全局,函数,eval
let 声明的变量只在代码块里有效,出代码块就无效了,就读取不到了
<script>
{
let greeting = 'hello';
}
console.log(greeting);
</script>
上面代码运行就不会输出,控制台会报错。如果换成 var:
<script>
{
var greeting = 'hello';
}
console.log(greeting);
</script>
就会正常输出,这是因为 var 没有块级作用域的概念,var 声明的属性会被添加到全局的属性 window 中,所以在花括号外就能读取到它,但 let 声明的变量就不行了,因为有块级作用域的概念,就只能在代码块里有效,所以在块外就读取不到了。
还有 if else while for,这些也都是块级作用域。
坑:做这个实验可别用什么 name 这种常见变量名,因为很可能已经被浏览器或者 Live Server 之类的用了
3.不存在变量提升
变量提升是:代码在执行之前,会先收集函数和 var 声明的变量,对于 var 声明的变量还会赋一个初始值 undefined
<script>
//在变量声明语句前,就可以输出变量
console.log(greeting);
var greeting = 'hello';
</script>
上面的代码会在控制台输出 undefined,这是因为存在变量提升,上面的实际执行逻辑就像:
<script>
var greeting;
//在变量声明语句前,就可以输出变量
console.log(greeting);
var greeting = 'hello';
</script>
如果使用 let 声明,就会报错,因为 let 声明的变量不存在变量提升:
<script>
console.log(greeting);
let greeting = 'hello';
</script>
4.不影响作用域链
<script>
{
let greeting = 'hello';
function fn() {
console.log(greeting);
}
fn();
}
</script>
正常运行,fn 函数作用域里没有 greeting,就会向上一层找 greeting 这个变量,然后就找到了,这就是作用域链的效果