var、let、const 都是用于声明变量的关键字,可以通过作用域、可变性、变量提升几个方面进行区分;
1,作用域
1)var的属于函数作用域,只能在函数内使用。若在函数外部声明变量,会变为全局变量;
function varfun(){//函数内声明的变量,只能在函数内部调用;var a1 = '11111' if(true) { //属于块级作用域console.log(a1) // 可以访问数据;}
}
varfun(); // 11111
console.log(a1); //报错 Uncaught ReferenceError: a1 is not defined
2)let 、const 拥有块级作用域,块级作用域是指用{}包裹的代码块,像,if、for、while等,在块级作用域声明的变量,只可以在块内访问。
function example() {if(true) {let y = 1;const z = 2;console.log(y); // 1console.log(z); // 2}console.log(y); // ReferenceError: y is not definedconsole.log(z); // ReferenceError: z is not defined
}
example()
2,变量提升:
1)var:存在变量提升的现象,变量提升表示在变量声明之前就可以访问变量,但变量值是undefind。
2)let、const不存在变量提升,在变量声明之前访问let或者const变量,会引发ReferenceError 错误。这种现象也被称作暂时性死区。
function example() {console.log(a); // undefinedconsole.log(b); // ReferenceError: Cannot access 'b' before initializationconsole.log(c); // ReferenceError: Cannot access 'c' before initializationvar a = '1'let b = '2'const c = '3'
}
example();
3,可变性
1)var和let 声明的变量可以重新赋值
function example() {var a = 1; let b = 2;a = 4b = 5; console.log(a, b); // 4 5
}
example();
2)const 一旦声明,必须初始化,并且赋值后不可以重新赋值。若const声明的是对象或者数组,对象的属性或者数组的元素是可以修改的。
function example() {const c = 3;const arr = [1, 2, 3];const obj = { name: 'John' };c = 4; //报错: TypeError: Assignment to constant variable.arr[1] = 4; // OKarr.push(5); // OKarr = [1, 8, 6]; //报错: TypeError: Assignment to constant variable.obj.name = 'Doe'; // OKobj = { name: 'Doe' }; //报错: TypeError: Assignment to constant variable.console.log(arr); // [1, 4, 3]console.log(obj); // { name: 'Doe' }
}
example();
4,重复声明:
1)var可以重复声明
2)let、const不可以重复声明
function example() {
// var可以重复声明var a = 1;var a = 2;console.log(a); // 2
// let不可以重复声明let b = 1;// let b = 2; // SyntaxError: Identifier 'b' has already been declaredconsole.log(b); // 1
// const不可以重复声明const c = 1;// const c = 2; // SyntaxError: Identifier 'c' has already been declaredconsole.log(c); // 1if(true) {var a = 3; // 这里的a是example函数作用域let b = 4; // 这里的b是块级作用域const c = 5; // 这里的c是块级作用域console.log(a); // 3 console.log(b); // 4console.log(c); // 5}
}
example();
5,使用场景
1)var:鉴于其函数作用域和变量提升的特点,容易引发错误,所以现在javascript开发中,var使用频率较低,一般在旧代码或者需要兼容老版本浏览器时使用。
2)let:当需要再块级作用域中声明变量,并且后续需要重新赋值时,建议使用let。例如:for循环
3)const:变量赋值后不需要再改变时,应该使用const,可以增强代码的可读性或者可维护性;