var、let 和 const 是 JavaScript 中用于声明变量的三种关键字,它们之间有一些关键的区别,这些区别主要体现在作用域、提升(hoisting)、重新赋值和重新声明方面。
- 作用域(Scope) :
- var:
var声明的变量具有函数作用域或全局作用域,具体取决于其声明位置。如果在函数内部声明,则其作用域为该函数;如果在函数外部声明,则为全局作用域。 - let 和 const:
let和const声明的变量具有块级作用域(block scope),即它们的作用域被限制在其声明的块({})内。这允许在块内部声明变量而不影响外部作用域。
- var:
<style>
.item {
width: 100px;
height: 50px;
border: solid 1px rgb(42, 156, 156);
float: left;
margin-right: 10px;
}
</style>
<body>
<div class="container">
<h2 class="page-header">点击切换颜色</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
//获取div元素对象
let items = document.getElementsByClassName('item');
//遍历并绑定事件
for(var i = 0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
// this.style.background = 'pink';
items[i].style.background = 'pink';
}
}
// 这里相当于
// 由于var具有函数作用域或全局作用域,不具有块级作用域,
//所以点击的时候会重复定义,会报错
// {
// var i = 0
// }
// {
// var i = 1
// }
// {
// var i = 2
// }
console.log(window.i);
//这里输出3 是因为item只有三个元素 i 为 0 1 2
// 最后一次自增到3 的时候,获取不到item 于是输出3
</script>
</body>
解决方法:这个时候只需要将var改为let,原因由上述作用域的定义所示
//获取div元素对象
let items = document.getElementsByClassName('item');
//遍历并绑定事件
//这里的var改为let
for(let i = 0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
items[i].style.background = 'pink';
}
}
// {
// let i = 0
// }
// {
// let i = 1
// }
// {
// let i = 2
// }
<script>
//声明常量
const SCHOOL = '尚硅谷';
//1. 一定要赋初始值
// const A;
// 不赋值初始值
//2. 一般常量使用大写(潜规则)
const a = 100;
//3. 常量的值不能修改
// SCHOOL = 'ATGUIGU'; //报错
//4. 块儿级作用域 :作用域内
const PLAYER = 'Aaaa';
{
const PLAYER = 'UZI';
console.log(PLAYER);
}
console.log(PLAYER);
//5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['UZI','MXLG','Ming','Letme'];
TEAM.push('Meiko');
console.log(TEAM);
- 提升(Hoisting) :
- var:
var声明的变量会被提升(hoisting)到其作用域的顶部,但变量的初始化不会提升。这意味着你可以在声明变量之前访问它(值为undefined)。
- var:
<script>
console.log(a); // undefined
var a = 2
console.log(a); //2
</script>
- let 和 const:
let和const声明的变量也会被提升,但它们不会被初始化,这意味着在声明之前访问这些变量会导致一个引用错误(ReferenceError)。
<script>
console.log(a); //报错
let a = 2
console.log(a);
</script>
<script>
console.log(a); //报错
const a = 2
console.log(a);
</script>
- 重新赋值(Reassignment) :
- var 和 let:使用
var和let声明的变量都可以被重新赋值。 - const:
const声明的变量必须被赋予一个初始值,并且这个值不能被重新赋值。但是,如果变量是一个对象或数组,那么你可以修改对象或数组内部的属性或元素,只是不能重新给变量分配一个全新的值。
- var 和 let:使用
- 重新声明(Redeclaration) :
- var:
var允许在同一个作用域内多次声明同一个变量,但后续声明不会改变变量的值(除非进行了赋值)。 - let 和 const:
let和const不允许在同一个作用域内或同一块内重复声明同一个变量。尝试这样做会导致语法错误(SyntaxError)。
- var:
<script>
var a = 0
let b = 1
const C = 2
console.log(a,b,C); // 0 1 2
a = 3
b = 4
console.log(a,b); // 3 4
C = 5 //报错
</script>
总结:
- 使用
var时,变量具有函数作用域或全局作用域,并允许提升和重新声明。 - 使用
let时,变量具有块级作用域,允许提升但初始化不会提升,支持重新赋值但不支持重新声明。 - 使用
const时,变量具有块级作用域,不允许重新赋值和重新声明,但可以修改复合类型(如对象和数组)的内部属性。
在现代 JavaScript 开发中,推荐使用 let 和 const 来声明变量,因为它们提供了更清晰的作用域和更严格的变量管理,有助于避免一些常见的错误。