• let和const


    let命令

    • 声明的变量,只在声明的代码块中有效

    • 适用于for循环

      for(let i=0;i<10;i++){
         //声明的i只在for循环体中有效,在外面不能访问
      }
      • 如下,i递增时,已定义的数组项中的i值,不会改变,因为无法访问到循环体中的i

        • 但若i是通过var定义的,则全局都可以访问,i递增时,数组项中的i也会改变

        for (let i = 0; i < 10; i++) {
               a[i]=function () {
                   console.log(i)
              }
          }
           a[6]();

    for循环中的作用域

    • for循环中,设置循环变量的部分和循环体中是两个独立的作用域

    • 若在此两个作用域中使用let定义同名变量,互不影响。但若是var定义同名变量,互相会影响

      for (let i = 0; i < 3; i++) {
         let i='看看';
         console.log(i)
      }

      //i等于0时进入循环,重新赋值为'看看',输出,继续判断i是否小于3,无法比较,停止循环
      for (var i = 0; i < 3; i++) {
         var i='看看';
         console.log(i)
      }

    不存在变量提升

    • 通过var声明的变量,在声明之前,会进行预解析。同样可以调用,返回undefined

    • 但通过let声明的变量,声明之前不会预解析,不能调用

      console.log(a);//undefined
      var a = 10;
      console.log(b);//报错
      let b = 20;

    暂时性死区

    本质:只要以进入当前作用域,所要使用的变量就已经存在了,但是还没有声明,不可获取。只有执行到了声明该变量那一行之后,才可以获取和使用该变量。

    • 只要某个块级作用域内,使用了let声明变量,则这个变量就绑定了此块级作用域,不会被外界影响

    • 此时即使是通过var在外部声明的变量,只要通过let在块级作用域内也声明了。在块级作用域内、声明前调用,也会报错

      var a = 3;
      if (true) {
         a = 10;
         let a;
      }
    • 此时typeof不再百分百安全

      typeof tmp;//报错
      let tmp=10;
    • 以下行为也会报错

      • 赋值时,x的声明并没有完成,依然会当做没有声明处理

      let x= x;

    不允许重复声明

    • let不允许在同一个作用域内重复声明同一个变量

      function func() {//报错
         let arg=20;
         var arg=10;
      }

      function func() {//报错
         let arg=20;
         let arg=10;
      }

      function func(arg) {//报错
         let arg;
      }
      func()

      function func(arg) {//不报错,不同作用域
            {
                 let arg
            }
        }
         func()

    块级作用域

    • let为函数新增了块级作用域

    块级作用域与函数声明
    • ES5规定,函数只能在顶级作用域和函数作用域中声明,不能在块级作用域中声明

    • 浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数

    • 但在ES6浏览器中,浏览器的实现只需遵守:

      • 允许在块级作用域内声明函数。

      • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。

      • 同时,函数声明还会提升到所在的块级作用域的头部。

    • 考虑到环境问题,在块级作用域内声明函数时最好使用表达式

    • ES6的块级作用域必须有{}

    const

    • const声明一个只读的常量,一旦声明常量的值就不能更改

    • const一旦声明变量,就必须立即初始化

    • 同样只在声明的块级作用域中有效

    • const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用

    const的本质

    • 实际上是保证声明的变量所指向的内存地址中所保存的值不能改变。

    • 对应简单的数据类型:数字、字符串等等,值就保存在变量指向的那个内存地址,等同于常量

    • 而数组、对象,因为其变量指向的地址中保存的依然是指向实际数据的指针,所以只能保证保存的指针不改变,而指针指向的实际数据可以改变,所以

      const a = [];
      a.push(1);//不报错
      console.log(a);
      a = [];//报错

    冻结对象

    • 如果真的想将对象冻结,应该使用

      const foo = Object.freeze({});
      foo.prop=123;//严格模式下报错
  • 相关阅读:
    UNIX网络编程--学习日记
    VC下ffmpeg例程调试报错处理
    Cholesky Decomposition
    [置顶] ORM框架Hibernate (二) 对象到关系多对一映射
    [置顶] rails2 升级到 rails3 过程详细记录
    python 连接MYSQL数据库(入门帖)
    【PAT】1005 Spell It Right
    Eclipse & MyEclipse下常用快捷键介绍
    HDU 2544
    你如何只用一个数组实现三个栈?
  • 原文地址:https://www.cnblogs.com/ashen1999/p/12559759.html
Copyright © 2020-2023  润新知