美文网首页
const 定义的变量可以被修改吗?

const 定义的变量可以被修改吗?

作者: 小王子__ | 来源:发表于2022-02-23 11:01 被阅读0次

    var、let、const相关问题

    • 1,var
    • 2,let
    • 3,const
    • 4,块级作用域
    • 5,三者区别
    • 6,const 定义的变量可以修改吗?
    • 7,经典面试题

    1,var

    1, 声明提升
    console.log(num) // undefined
    var num = 100
    
    2, 变量覆盖
    var num1 = 100
    var num1 = 200
    conosle.log(num1) // 200
    
    3, 没有块级作用域
    function fn() {
      for (var i = 0; i <= 5; i++) {
        console.log(i)  // 0 1 2 3 4 5
      }
      console.log(i)  // 6
    }
    fn()
    

    2,let

    1, let 声明的变量具有块级作用域的特征
    function fn() {
      let a = 10
    }
    console.log(a) // a is not defined
    
    2, 在同一个块级作用域,不能重复声明变量
    function fn() {
      let a = 10
      let a = 20
    }
    console.log(a) // Identifier 'a' has already been declared
    
    3, let 声明的变量不存在变量提升,换种说法就是let声明存在暂时性死区(TDZ)
    console.log(num) // Cannot access 'num' before initialization
    let num = 10
    
    

    3,const

    1, const 声明的变量具有块级作用域的特征
    function fn() {
      const a = 10
    }
    console.log(a) // a is not defined
    
    2, 在同一个块级作用域,不能重复声明变量
    function fn() {
      const a = 10
      const a = 20
    }
    console.log(a) //  Identifier 'a' has already been declared
    
    3, const 声明的变量不存在变量提升,换种说法就是const声明存在暂时性死区(TDZ)
    console.log(num) // Cannot access 'num' before initialization
    const num = 10
    
    4, const 声明一旦定义后,不能修改
    const num = 100
    num = 200
    console.log(num) // Assignment to constant variable.
    

    4,块级作用域

    ES5中作用域有:全局作用域、函数作用域,没有块级作用域的概念。

    ES6新增了块级作用域,由 {} 包括,if 语句for 语句里面的 {} 都属于块作用域

    {
      var num = 100
      console.log(num) // 100
    }
    console.log(num) // 100 可见,通过var定义的变量可以跨块作用域访问到
    
    function fn() {
      var num = 100
      console.log(num) // 100
    }
    console.log(num) // num is not defined 可见,通过var定义的变量不能跨函数作用域访问到
    
    if (true) {
      var num = 100
    }
    console.log(num) // 100
    
    for (var i = 0; i <= 5; i++) {
      var num = 100
    }
    console.log(i) // 6
    console.log(num) // 100
    if 语句和 for 语句中用 var 定义的变量可以在外面访问到,可见,if 语句和 for 语句属于块级作用域,不属于函数作用域
    

    5,三者区别

    • var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问
    • let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
    • const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,且不能修改
    // 块级作用域
    {
      var a = 100
      var b = 200
      var c = 300
      var a1
      let b1
      // const c1
      console.log(a) // 100
      console.log(b) // 200
      console.log(c) // 300
      console.log(a1) // undefined
      console.log(b1) // undefined
    }
    console.log(a) // 100
    console.log(b) // 200
    console.log(c) // 300
    
    // 函数作用域
    (function fn() {
      var a = 100
      let b = 200
      const c = 300
      console.log(a) // 100
      console.log(b) // 200
      console.log(c) // 300
    })()
    console.log(a) // a is not defined
    console.log(b) // b is not defined
    console.log(c) // c is not defined
    

    6,const 定义的变量可以修改吗?

    const 定义的基本类型不能改变,但是定义的对象是可以通过修改对象属性等方法改变的

    const num = 100
    num = 200
    console.log(num) // Assignment to constant variable.
    
    const person = {
      name: 'Tom',
      age: 18
    }
    person = {
      name: 'Jerry',
      age: 20
    }
    console.log(person) // Assignment to constant variable.
    
    const person = {
      name: 'Tom',
      age: 18
    }
    person.name = 'Jerry'
    console.log(person) // {name: 'Jerry', age: 18}
    

    基本数据类型的变量保存在栈区中,基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响其他的变量。

    引用数据类型的值是同时保存在栈内存和堆内存的对象,栈区保存了对象在堆区的地址。

    const 声明的 person 给属性重新赋值是可以的,但是给 person 重新赋值是不可以的,那样会改变 person 在栈区的地址

    7,经典面试题

    for (var i = 0; i <= 5; i++) {
      setTimeout(function() {
        console.log(i)
      }, 1000)
    }
    console.log(i)
    
    image

    setTimeout 是异步执行的,1000ms后向任务队列里添加一个任务,只有主线程的全部执行完才会执行任务队列里的任务,所以当主线程 for 循环执行完之后 i 的值为 6, 这时候再去执行任务队列里执行任务, i 全部是 6。

    每次 for 循环的时候 setTimeout 都会执行,但是里面的 function 则不会执行被放入任务队列,因此放了 6 次, for 循环的 6 次执行完之后不到 1000ms, 100ms后全部执行任务队列里的函数,所以输出 6 个 6。

    for (let i = 0; i <= 5; i++) {
      setTimeout(function() {
        console.log(i)
      }, 1000)
    }
    console.log(i)
    
    image

    let定义的 i 事块级作用域,每个 i 只能存活到大括号结束,并不会把后面的 for 循环的 i 值赋给前面的 setTimeout 中的 i,而var 定义的 i是局部变量,这个 i 的生命周期不受for 循环的大括号限制。

    相关文章

      网友评论

          本文标题:const 定义的变量可以被修改吗?

          本文链接:https://www.haomeiwen.com/subject/ytrolrtx.html