let、const、var的区别有哪些

本文详细对比了ES5中的var与ES6中引入的let和const在变量声明上的区别,包括变量提升、作用域、重复声明、模块级作用域及常量特性等关键概念。

1.var是在ES5的时候提出的,let和const是在ES6上提出的。

2.在定义变量的时候,var存在变量的提示,let和const不存在变量的提升

var a = 100;
consoloe.log(a);//100

consoloe.log(a);//underfinde 证明这个时候a已经声明,只是没有赋值
var a = 100;

consoloe.log(b);//ReferenceError: b is not defined 找不到b这个变量
let b = 100;

consoloe.log(c);//ReferenceError: c is not defined 找不到c这个变量
const c = 100;

3.var 声明的变量是会挂载在window对象上,而let和const声明的变量不会

var a = 100;
console.log(a,window.a); //100 100

let b = 100;
console.log(b,window.b); //100 undefined

const c = 100;
console.log(c,window.c);//100 undefined

4.let和const声明的变量都会形成模块级作用域

{
   var a = 100;
   let b =100;
}
cosnole.log(a);//100
cosnole.log(b);//ReferenceError: b is not defined 找不到b这个变量
{
   var a = 100;
   cosnt b =100;
}
cosnole.log(a);//100
cosnole.log(b);//ReferenceError: b is not defined 找不到b这个变量

5.在相同的模块作用域下,let和const不能声明相同名称的变量,而var则是通过后面相同变量名称的变量覆盖之前的变量内容。

var a = 100;
var a = 10;
console.log(a);//10

let b = 100;
let b = 10;
console.log(b);//Identifier 'b' has already been declared b这个变量已经被声明了 

const c = 100;
const c = 10;
console.log(c);//Identifier 'c' has already been declared b这个变量已经被声明了 

6.let和const都存在暂时性的死区,即只有在模块区域内存在let和const命令声明变量,它所声明的变量就绑定在这个区域,不在受外部的影响。

var a = 100;

if(true){
    a = 10;
    //在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,
    // 而这时,还未到声明时候,所以控制台Error:a is not defined
    let a = 1;
}

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

7.var和let声明的变量是可以修改的,const声明的是一个常量,一旦声明之后,常量的值就不能够改变了。

const f = 10;
// f= 11;
// console.log(f) //报错 不能进行重复声明

const obj = {
    name: '小明',
    age: 18
}
obj.age = 20
console.log(obj) //{ name: '小明', age: 20 }  
//const声明常量,不允许对变量重新赋值。对于引用类型的值而言,只要在栈内存保存的地址值不变即可。

本文参考了阮一峰的ES6

<think>嗯,用户问的是JavaScript中letconstvar区别。这个问题我之前学过,但可能需要仔细回忆一下才能准确回答。首先,我得确定这三个关键字在作用域、提升、重复声明和重新赋值等方面的不同。 首先,作用域方面。我记得var是函数作用域,而letconst是块级作用域。比如,在函数内部用var声明的变量,整个函数内都有效,而如果在if语句块中用letconst声明,就只在那个块里有效。对吗?比如: function example() { if (true) { var a = 1; let b = 2; const c = 3; } console.log(a); // 输出1,因为var是函数作用域 console.log(b); // 报错,b未定义,因为let是块级作用域 console.log(c); // 同样报错 } 对吧?这样用户就能理解作用域的区别了。 然后是变量提升的问题。var声明的变量会被提升到作用域的顶部,但初始化是undefined,而letconst虽然也有提升,但在声明前访问会报错,也就是暂时性死区。比如: console.log(x); // undefined,因为var提升 var x = 5; console.log(y); // 报错,因为let不会初始化 let y = 10; 这样用户就能明白变量提升的不同处理方式了。 接下来是重复声明。var允许重复声明同一个变量,后面的会覆盖前面的,但letconst不行,会直接报错。例如: var a = 1; var a = 2; // 没问题 let b = 3; let b = 4; // 报错,重复声明 这个例子能清楚说明问题。 再来看重新赋值。const声明的是常量,一旦赋值不能改变。但如果是对象或数组,属性或元素可以修改,只是不能重新赋值整个变量。而letvar可以重新赋值。比如: const arr = [1, 2]; arr.push(3); // 允许 arr = [4, 5]; // 报错 let num = 10; num = 20; // 没问题 这部分需要注意说明const的限制在哪里。 全局作用域下声明的话,var变量会成为全局对象的属性,比如window,而letconst不会。例如: var globalVar = 'var'; let globalLet = 'let'; console.log(window.globalVar); // 'var' console.log(window.globalLet); // undefined 这样用户就能理解在全局作用域下的差异。 总结时,要给出使用建议:尽量用const,需要重新赋值时用let,避免使用var。这样可以避免作用域和提升带来的问题。 不过,有没有可能用户会问到更多细节?比如暂时性死区的具体表现,或者块级作用域在循环中的应用?比如for循环中使用letvar区别,可能会引发经典的问题: for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // 输出3次3 } for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 100); // 输出0,1,2 } 这时候,var由于函数作用域,i在循环结束后变成3,而let每次循环都是新的块作用域,所以j的值保留正确。这个例子可以进一步说明块级作用域的重要性。 可能用户需要这些例子来加深理解。所以,在回答中可以适当加入这些案例,帮助用户更好地掌握区别。 最后,要确保回答结构清晰,分点说明每个区别,并给出示例,这样用户能逐步理解。同时,使用中文,避免技术术语过于复杂,让初学者也能明白。</think>### `let`、`const`、`var` 的区别(JavaScript) 以下是三者在作用域、变量提升、重复声明和重新赋值等方面的对比: --- #### **1. 作用域** - **`var`**:函数作用域(仅在声明它的函数内有效)。 ```javascript function func() { var a = 1; if (true) { var a = 2; // 覆盖外层的 a } console.log(a); // 输出 2 } ``` - **`let`/`const`**:块级作用域(在 `{}`、`if`、`for` 等代码块中有效)。 ```javascript if (true) { let b = 2; const c = 3; } console.log(b); // 报错:b 未定义 console.log(c); // 报错:c 未定义 ``` --- #### **2. 变量提升** - **`var`**:变量声明会被提升到作用域顶部,但值为 `undefined`。 ```javascript console.log(x); // undefined(不报错) var x = 10; ``` - **`let`/`const`**:存在暂时性死区(TDZ),声明前访问会报错。 ```javascript console.log(y); // 报错:未初始化 let y = 20; ``` --- #### **3. 重复声明** - **`var`**:允许重复声明。 ```javascript var a = 1; var a = 2; // 合法 ``` - **`let`/`const`**:禁止重复声明。 ```javascript let b = 3; let b = 4; // 报错:重复声明 ``` --- #### **4. 重新赋值** - **`var`/`let`**:可以重新赋值。 ```javascript let num = 10; num = 20; // 合法 ``` - **`const`**:声明后不可重新赋值(常量)。 ```javascript const PI = 3.14; PI = 3.1415; // 报错 ``` > **注意**:如果 `const` 声明的是对象或数组,其属性或元素可以修改。 > ```javascript > const arr = [1, 2]; > arr.push(3); // 合法 > arr = [4, 5]; // 报错 > ``` --- #### **5. 全局作用域下的行为** - **`var`**:在全局作用域下声明时,会成为 `window` 对象的属性。 ```javascript var globalVar = "hello"; console.log(window.globalVar); // "hello" ``` - **`let`/`const`**:不会绑定到 `window` 对象。 ```javascript let globalLet = "world"; console.log(window.globalLet); // undefined ``` --- ### **总结使用建议** 1. **优先使用 `const`**:适合声明常量或不需要重新赋值的变量。 2. **需要重新赋值时用 `let`**:替代 `var` 以避免作用域污染。 3. **避免使用 `var`**:防止变量提升和函数作用域导致的意外错误。 --- ### **经典案例对比** ```javascript // var 的问题:循环中的变量泄露 for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // 输出 3, 3, 3 } // let 的块级作用域解决此问题 for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 100); // 输出 0, 1, 2 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值