zoukankan      html  css  js  c++  java
  • let 、 const 、 块级作用域

    写在前面

    ES6 声明变量的 6 种方法

    ES5 只有两种声明变量的方法:var 命令和 function 命令。ES6 除了添加 letconst 命令,后面章节还会提到,另外两种声明变量的方法:import 命令和 class命令。所以,ES6 一共有 6 种声明变量的方法。

    块级作用域

    为什么需要块级作用域

    ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。比如内层变量可能会覆盖外层变量;用来计数的循环变量泄露为全局变量

    • let 实际上为 JavaScript 新增了块级作用域。
      块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

    块级作用域与函数声明

    • 在浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于 var 声明的变量;
    • 另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

    let

    不存在变量提升

    • let 所声明的变量只在其所在的代码块内有效
    • let 不存在变量提
      var 所声明的变量在脚本运行前就将变量都定义了,在脚本中的赋值语句中再对其进行赋值操作,所以变量可以在声明之前使用,值为undefined
      let 纠正了这种语法行为,它所声明的变量一定要在变量声明后使用,否则报错

    暂时性死区(temporal dead zone,简称 TDZ)

    • ES6 中如果在区块中存在 letconst ,则区块对这些命令声明的变量从一开始就形成了封闭作用域,凡是在声明之前使用这些变量都会报错
    • ES6 规定暂时性死区和 letconst 语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。
    • 在没有let之前,typeof 运算符是百分之百安全的,永远不会报错。现在这一点不成立了。这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就报错。

    ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。
    总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

    不允许重复声明

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

    const

    • const 声明一个只读的常量。一旦声明,常量的值就不能改变;(这意味着,const 一旦声明变量,就必须立即初始化,不能留到以后赋值)
    • const 的作用域与let命令相同:只在声明所在的块级作用域内有效。
    • const 命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

    const 的本质

    const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const 只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    • 如果真的想将对象冻结,应该使用Object.freeze方法。

      const foo = Object.freeze({});
      // 常规模式时,下面一行不起作用;
      // 严格模式时,该行会报错
      foo.prop = 123;</pre>
      

      上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。
      除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

      var constantize = (obj) => {
          Object.freeze(obj);
          Object.keys(obj).forEach( (key, i) => {
              if ( typeof obj[key] === 'object' ) {
                  constantize( obj[key] );
              }
          });
      };
      
    HAVE A NICE DAY!
  • 相关阅读:
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Maximum Depth of Binary Tree
    Sharepoint 2013 创建TimeJob 自动发送邮件
    IE8 不能够在Sharepoint平台上在线打开Office文档解决方案
    TFS安装与管理
    局域网通过IP查看对方计算机名,通过计算机名查看对方IP以及查看在线所有电脑IP
    JS 隐藏Sharepoint中List Item View页面的某一个字段
    SharePoint Calculated Column Formulas & Functions
    JS 两个一组数组转二维数组
  • 原文地址:https://www.cnblogs.com/apimhnkj/p/10123435.html
Copyright © 2011-2022 走看看