var ,let,const的区别
- 1.let和const声明的变量具有块级作用域,var声明的变量不具有块级作用域
- 2.let和const声明的变量不可以重复声明,var 声明的变量可以重复声明
- 3.let和const声明的变量具有暂时性死区,var声明的变量则没有,但var有变量提升
- 4.const声明的变量不可修改,所以一开始就要将const初始化赋值,let和var声明的变量可以修改
详细内容请看下文:
块级作用域
在ES6中新增了let命令,用来声明变量。它的用法类似于var,但是let所声明的变量,只在let命令所在的代码块(块级作用域)内有效。
{
let a = 10;
var b = 1;
}
console.log(a) //报错: a is not defined
console.log(b) //1
作用域: 指某一变量和方法具有访问权限的代码空间(一个变量或方法可以在哪个范围中使用)。在JS中,作用域是在函数中维护的。表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,也指上下文执行环境。作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。
在JS中作用域分为三种:ES5(全局作用域,局部作用域),ES6(块级作用域)。
- 1.1-js三种作用域介绍
- 1.作用域概念(Scope) : 变量可以起作用的范围区域
- 1.1 ES5 有两种作用域
- a.全局作用域(Global Scope) : 函数外面声明的变量,称之为全局变量。 可以在页面任何地方被访问
- 全局变量生命周期 : 从页面加载 -> 到页面关闭
- b.局部作用域(Local Scope) : 函数里面声明的变量,称之为局部变量。 只能在函数里面被访问
- 局部变量生命周期 : 从函数开始执行 -> 到函数执行结束
- a.全局作用域(Global Scope) : 函数外面声明的变量,称之为全局变量。 可以在页面任何地方被访问
- 1.1 ES5 有两种作用域
- 1.2 ES6 在ES5原有基础上新增第三种作用
- c.块级作用域(Block Scope) : (1)let/const关键字声明 (2) 大括号里面声明(包括函数)
- 块级变量声明周期 : 从大括号开始 -> 到大括号结束
- c.块级作用域(Block Scope) : (1)let/const关键字声明 (2) 大括号里面声明(包括函数)
1-全局作用域
//1.1 全局作用域 : 在函数外部声明的变量,可以在页面任何地方被访问
var a = 10;//全局变量
let b = 20;//全局变量
function fn() {
console.log(a, b);//10,20
};
fn();
console.log(a, b);//10,20
console.log(window.a);//10
console.log(window.b);//undefined
2-局部作用域
//1.2 局部作用域 : 在函数里面声明的变量, 只能在函数内部被访问
function fn() {
var a = 10;//局部变量
let b = 20;//局部变量
console.log(a,b);//10,20
};
fn();
console.log(a);//报错 a is not defined
console.log(b);//报错 b is not defined
3-块级作用域
//1.3 块级作用域 : 在大括号里面 且 使用let声明的变量
if(true){
var a = 10;//全局变量
let b = 20;//块级变量(块级作用域 :只在大括号内部起作用)
console.log(a,b);//10,20
};
console.log(a);//10
// console.log(b);//报错 b is not defined
局部作用域优先级>块级作用域(在函数体大括号内部,无论使用什么关键字声明var/let/const都是局部作用域)
总结一:let和const都具有块级作用域,var声明的变量不具有块级作用域。
重复声明:
var a = 10;
var a = 20;
console.log(a); //20
let b = 10;
let b = 20; //报错:Uncaught SyntaxError: Identifier 'b' has already been declared
let a = 20; //报错:Uncaught SyntaxError: Identifier 'b' has already been declared
const a = 10; //报错:Uncaught SyntaxError: Identifier 'b' has already been declared
总结二:let和const声明的变量不可以重复声明,var 声明的变量可以重复声明
暂时性死区
console.log(a); //undefined
var a = 10;
console.log(b); //报错:作用域.html:211 Uncaught ReferenceError: Cannot access 'b' before initialization at
let b = 10;
var:变量提升(在声明前可以访问变量,获取的是undefined)
- js编译器在预解析阶段,会把变量的声明提升到当前作用域最顶端,赋值语句还是在原地
let:暂时性死区(在声明前不可以访问变量,会报错)
- 暂时性死区(隐式变量提升)。一旦在当前作用域使用let,则js编译器在预解析阶段会将该变量"绑定"这个作用域,不受任何外部影响
总结三:let和const声明的变量具有暂时性死区,var声明的变量则没有,但var有变量提升
修改变量
var a = 10;
a = 20;
console.log(a); //20
let b = 10;
b = 20;
console.log(b); //20
const c = 10;
c = 20; //报错:Uncaught TypeError: Assignment to constant variable.
const d;
d = 10; //报错:Uncaught TypeError: Assignment to constant variable.