var | let | const | |
---|---|---|---|
作用域 | 全局作用域 | 局部作用域 | 局部作用域 |
变量声明 | var web; //正确 | let web; //正确 | const WEB; //报错,必须有初始值,如const WEB ="baidu.com" |
是否可修改 | 可修改 | 可修改 | 若为基本数据类型,不可修改;若为引用数据类型,可修改值,不可修改引用地址 |
是否可重复声明 | 可以 | 报错 | 报错 |
变量提升 | 是 | 否 | 否 |
- 作用域
var 为全局作用域,而let和const是局部作用域,即在块作用域内使用let声明的变量或const声明的常量对块域外部无影响,简单说就是在一个{}里面生效。
if (true) {
var a = 1;
let b = 2;
const c = 3;
}
console.log(a); //a打印出来为 1
console.log(b); //b is not defined
console.log(c); //c is not defined
注意:
- 使用var声明变量有时会造成循环内变量过度共享。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
- var全局声明的变量存在于window对象中,但let声明的全局变量不是全局对象的属性。这就意味着,你不可以通过window.变量名的方式访问这些变量。它们只存在于一个不可见的块的作用域中,这个块理论上是Web页面中运行的所有JS代码的外层块。
let a = 1;
var b = 2;
console.log(window.a);//undefined
console.log(window.b);//2
- 变量声明
var和let可以仅声明不赋值,但是const必须赋值,否则报错。(使用const声明的常量建议大写)
var a = 1 //正确
let b = 1 //正确
const C = 1 //正确
var d //正确 d打印为undefined
let e //正确 e打印为undefined
const F //错误 Uncaught SyntaxError: Missing initializer in const declaration
- 是否可修改
var和let声明的变量,可随意修改;const声明的常量,若为基本数据类型不可修改,若为引用数据类型,可修改值,不可修改引用地址。
var a = 1;
a = 2;
console.log(a); // 2
let b = 1;
b = 2;
console.log(b); // 2
//c为基本数据类型不可修改
const c = 1;
c = 2; //报错
//d为引用数据类型
const d = [1, 2, 3];
d.push(4); //对引用数据类型进行值的修改可进行
console.log(d); // [1,2,3,4]
d = [1, 2, 3, 4, 5]; //对引用数据类型进行地址修改,报错
d.lengh = 0;//清空数组(若为d = []会报错,因为修改了引用地址)
- 是否可重复声明
同一作用域下,使用var声明的变量可以重复声明,当然后面的会覆盖前面的。而使用let声明的变量或const声明的常量不可重复声明。但不同作用域下,三者都可以重复声明变量。
var a = 1;
var a = 2; //不报错,可重复声明
console.log(a); // 2
//let 和 const 情况相同
let a = 3; //报错,上面已经声明过a(var 声明的也不可以)
let b = 1;
let b = 2; //报错,上面已经声明过b
- 变量提升
var 声明的变量会进行变量提升,但是赋值不提升;let声明的变量或const声明的常量不会提升。
console.log(a); // a为undefined
var a = 1;
console.log(a); // a为1
//let和const情况相同
console.log(b); //报错,提示 b is not defined
let b = 1;
console.log(b); // b为1