一:let 、const 与 var 相比存在 块级作用域,一个{} 就是一个块
var 定义的变量只在(全局) 和 (函数)中 有作用域,其余都可用
if (true) {
var a = 5
}
console.log(a) // 5
if(){} 不是函数,所以 a 的作用域是全局
if (true) {
let a = 5
}
console.log(a) // 报错 Uncaught ReferenceError: a is not defined
if (true) {
const a = 5
}
console.log(a) // 报错 Uncaught ReferenceError: a is not defined
let、const 存在块级作用域,所以 a 只在 {} 中有效,{} 外访问会报错
二:let 、const 不存在变量提升
let a = 5
function fn() {
console.log(a) // Uncaught ReferenceError: a is not defined
// 定义之前使用都是 暂时性死区 TDZ
let a = 0
}
fn()
三:let、const 不可以在同一个块级作用域内重复定义
let a = 5
let a = 0
console.log(a) // Uncaught SyntaxError: Identifier 'a' has already been declared
const b = 5
const b = 0
console.log(b) // Uncaught SyntaxError: Identifier 'b' has already been declared
let:不加关键字可以修改值
let a = 5
a = 0
console.log(a) // 0
const 一旦定义值就不可以更改:否则报错
const b = 5
b = 0
console.log(b) // Uncaught TypeError: Assignment to constant variable
例子:
for(var i = 0; i < 10; i++) {
}
console.log('循环外', i) // 循环外 10
代码从上向下执行的,var 相当于定义在了全局,for 循环结束后 i = 10
for(let i = 0; i < 3; i++) {
console.log(i) // 0 1 2 循环3次
}
console.log('循环外', i) // Uncaught ReferenceError: i is not defined
let 只在 for 循环的 {} 内有效~
for 循环()是一个作用域,{ } 里面又是一个作用域~ 这个不算重复定义 不在一个块级作用域内。。
for(let i = 0; i < 3; i++) {
let i = 'abc'
console.log(i)
}
// 输出3次 abc
{
let a = 7
{
let a = 6
{
let a = 5
console.log(a) // 5
}
console.log(a) // 6
}
console.log(a) // 7
}
自己找自己的相应作用域的a
{{{let a = 7} console.log(a)}} // Uncaught ReferenceError: a is not defined
有时候面试题, 笔试题 这样迷惑你~
例子:
var arr = []
for(var i = 0; i < 3; i++) {
arr[i] = function() {
console.log(i)
}
arr[i]() // 0 1 2
}
arr[0]() // 3
循环完了,i 是 3 了,arr[0]() 中的 i 因为是var 定义的,相当于全局变量,共享
想要解决这个问题,每次都输出相应的值,使用立即调用函数,以便在每次迭代中强制创建变量的一个新副本
var arr = []
for(var i = 0; i < 3; i++) {
arr[i] = (function(i) {
return function () {
console.log(i)
}
})(i)
arr[i]() // 0 1 2
}
arr[0]() // 0
上面立即调用函数返回一个函数
var arr = []
for(let i = 0; i < 3; i++) {
arr[i] = function() {
console.log(i)
}
arr[i]() // 0 1 2
}
arr[0]() // 0
arr[0]() 中的 i ,因为是 let 定义的 存在会计作用域,所以绑定的是各自的~
(四) 使用const 声明对象
const 会阻止变量绑定与变量自身值的修改,但不会阻止对变量成员的修改
1. 修改数组
const arr = [1, 2, 3]
arr.push(7)
console.log(arr) // [1,2,3,7]
2. 修改对象
const obj = {
name: 'ZHOU',
age: 21
}
obj.name = 'ee'
console.log(obj) // {name: "ee", age: 21}
可以修改成功~
但是如果重新复制就会报错:
const obj = {
name: 'ZHOU',
age: 21
}
obj = {name: 'ee'}
注意:const 阻止的是对于变量绑定的修改,而不阻止对成员值的修改。不可以重新赋值
var funcs = [],
object = {
a: true,
b: true,
c: true
};
// 不会导致错误
for (const key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次输出 "a"、 "b"、 "c"
});
const 能够在 for-in 与 for-of 循环内工作,是因为循环为每次迭,代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值
总结:let 与 const 的表现在很多情况下都相似于 var ,然而在循环中就不是这样。在 for-in与 for-of 循环中, let 与 const 都能每一次迭代时创建一个新的绑定,这意味着在循环体内创建的函数可以使用当前迭代所绑定的循环变量值(而不是像使用 var 那样,统一使用循环结束时的变量值)。