# var、let、const区别？

#### 重复声明

```javascript
var a = 1;
var a = 2;

let b = 1;
let b = 2; //Identifier 'b' has already been declared

const c = 1;
const c = 2; //Identifier 'c' has already been declared
```

#### 变量提升

```javascript
console.log(a);
var a = 1;

console.log(b);  //Uncaught ReferenceError:Cannot access 'b' before initialization
let b = 1;

console.log(c);  //Uncaught ReferenceError:Cannot access 'c' before initialization
const c = 2;
```

#### 顶层对象

```javascript
var a = 1;
console.log(window.a)  //1

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

const c = 1;
console.log(window.c)  //undefined
```

#### 重新赋值

```javascript
var a = 'hello';
a = 'world';
console.log(a)   //'world'

let a = 'hello';
a = 'world';
console.log(a)   //'world'

const a = 'hello';
a = 'world';   //Uncaught TypeError: Assignment to constant variable.

const a = {x:'hello'}
a.y = 'world'
console.log(a)   //{x:'hello',y:'world'}
```

#### 块级作用域

```javascript
{ 
  var i = 9;
} 
console.log(i);  // 9

{ 
  let i = 9;     // i变量只在 花括号内有效！！！
} 
console.log(i);  // Uncaught ReferenceError: i is not defined
```

最常见使用场景

```javascript
for (var i = 0; i <10; i++) {  
  setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
    console.log(i);        // 执行此代码时，同步代码for循环已经执行完成
  }, 0);
}
// 输出结果
10   共10个

// i虽然在全局作用域声明，但是在for循环体局部作用域中使用的时候，变量会被固定，不受外界干扰。
for (let i = 0; i < 10; i++) { 
  setTimeout(function() {
    console.log(i);    //  i 是循环体内局部作用域，不受外界影响。
  }, 0);
}
// 输出结果：
0  1  2  3  4  5  6  7  8 9
```

### 总结

|       | var | let | const            |
| ----- | --- | --- | ---------------- |
| 重复声明  | ✓   | ✕   | ✕                |
| 变量提升  | ✓   | ✕   | ✕                |
| 顶层对象  | ✓   | ✕   | ✕                |
| 重新赋值  | ✓   | ✓   | ✕（基础类型不可，引用类型可以） |
| 块级作用域 | ✕   | ✓   | ✓                |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://function.gitbook.io/febook/javascript/varletconst-qu-bie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
