var
1. 存在变量提升
console.log(a);//undefined
var a = '1';
2. var没有块级作用域
//var在循环内使用,循环外也可以使用
for(var i = 0;i < 5;i++){
console.log('for:',i);
}
console.log('outFor',i);
// for: 0
// for: 1
// for: 2
// for: 3
// for: 4
// outFor 5
//-----------------------------------------------------------------
//在上面例子的基础上我们加强一下理解
//eg:我们全局声明了数组arr,
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
};
}
arr[2](); //5
//代码解释:
//上面代码中,var声明的i全局范围都可访问,因此全局只有一个变量i。
//每次循环,i的值都会自动++。
//给数组arr赋值的函数其内部打印的i,都是一个。
//所以,输出的是最后一轮的i的值,也就是 5;
3. 声明:可以反复定义
var a =1;
var a =2;
//a:2
let
1. 不存在变量提升
console.log(a);//Uncaught ReferenceError: a is not defined;
let a = '1';
2. let有块级作用域
{
var x = 10; // 使用 var 声明的变量具有函数作用域,并非真正的块级作用域
let y = 20; // 使用 let 声明的变量具有块级作用域
}
console.log(x); // 输出:10,因为 var 声明的变量具有函数作用域,在块外部仍然可访问
console.log(y); // 报错:y is not defined,因为 let 声明的变量具有块级作用域,在块外部无法访问
//熟悉了上面的,我们来深入了解let
//let在循环内使用,外部无法访问
for(let i = 0;i < 5;i++){
console.log('for:',i);
}
console.log('outFor',i);
// for: 0
// for: 1
// for: 2
// for: 3
// for: 4
// outFor i is not defined
//-----------------------------------------------------------------
//在上面例子的基础上我们加强一下理解
//eg:我们全局声明了数组arr,for内用let声明i
var arr = [];
for (let i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
};
}
arr[2](); //2
arr[5](); //5
//代码解释:
//let 声明的i会产生一个块级作用域互补影响下;
//{
// arr[0] = function () {
// console.log(0);
// };
//}
//.
//.
//{
// arr[5] = function () {
// console.log(5);
// };
//}
3. 声明:不可重复声明
let a = 1;
let a = 2;
//他会告诉你a已经声明了
//Uncaught SyntaxError: Identifier 'a' has already been declared
const
1. 声明常量,一旦声明就不可更改,因此我们在声明的时候就要初始化值;
2. 这样设计的目的是为了确保代码的可靠性和安全性,防止意外的变量修改;
//---擅自更改---
const x= 'aaa';
x = '123';
//===报错===
// Assignment to constant variable.
//---只声明不赋值---
const x
//===报错===
//Uncaught SyntaxError: Missing initializer in const declaration
//在const声明中缺少初始化式
⚠️:如果声明的是复合类型数据,可以修改其属性。
const obj = {a:'1'}
obj.a = 2
//obj {a: 2}
1. 不存在变量提升
console.log(a)// Uncaught ReferenceError: a is not defined
const a = 1
2. const有块级作用域
const的作用域与let相同,只在声明所在的块级作用域内有效。
{
const str = 'aaa'
console.log('块内:',str) //块内:aaa
}
console.log('块外:',str) //str is not definedat
3. 声明:不可重复声明
区别总结:
上面已经一一说明的每个声明的含义和使用规则,下面我用表格的形式总结一下:
变量提升 | 块级作用域 | 重复声明 | |
var | ✅ | ❌ | ✅ |
let | ❌ | ✅ | ❌ |
const | ❌ | ✅ | ❌ |
块级作用域优点
我们在es6之前使用var来声明,但是因为块级作用域的情况,ES6后新增了let和const
其优点在于
避免变量污染: 块级作用域可以使变量的作用范围仅限于一个代码块内部,防止变量泄漏到其他代码块中,从而避免了变量污染问题。
避免命名冲突: 在 JavaScript 中,全局作用域中声明的变量很容易与其他模块或库中的变量重名,导致命名冲突。使用块级作用域可以避免这种问题,因为在不同的代码块中声明的变量将彼此独立,不会发生命名冲突。
提高程序的可读性: 通过将相关变量定义在同一个代码块中,可以使程序更易读、易理解。如果一个变量只在一个特定的代码块中使用,那么将其定义在该代码块内部可以更加清晰地表达变量的作用范围。
提高程序的可维护性: 使用块级作用域可以降低程序的耦合度,使不同的代码段之间具有更好的独立性。这样,在修改一个代码块时,不会影响到其他代码块,从而提高程序的可维护性。