let const 块级作用域

本文探讨了JavaScript中的let和const相对于var的块级作用域特性,包括它们不存在变量提升、不允许在同一作用域内重复定义的规则。通过实例展示了let如何在for循环中正确作用,而const声明的对象虽然不能改变其引用,但可以修改其成员。总结了在for-in和for-of循环中,let和const如何避免变量污染,确保每次迭代的独立性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一: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 那样,统一使用循环结束时的变量值)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值