zoukankan      html  css  js  c++  java
  • ES6初体验——(1)let和const命令

      前言:

      参考书籍:ECMAScript 6 入门    链接: http://es6.ruanyifeng.com/  阮一峰老师,书中示例详尽,此处只做简单梳理和理解,仅作督促自己学习使用

      1、let命令,用来声明变量。用法类似于 var,但是所声明的变量,只在let命令所在的代码块内有效。而ES5中,是没有块级作用域的概念的。

    var a = [];
    for (var i = 0; i < 10; i++) {//i由var定义,属于全局变量,i只定义了一次,每次循环,i的值递增,for循环执行完毕,i的值变成10,所以输出10
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 10
    var a = [];
    for (let i = 0; i < 10; i++) {//i由let定义,只在当轮循环有效,即每一轮循环的i都是重新声明的,
      a[i] = function () {        //由于JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算
        console.log(i);
      };
    }
    a[6](); // 6
    a[3](); // 3

      for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

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

      var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined,(这是因为预解析的缘故)。但是由let声明的变量则不存在变量提升现象,即不被预解析,它要求变量必须在声明语句之后才可以使用,否则会抛出错误。

    console.log(foo); // Uncaught ReferenceError: foo is not defined    始终没有声明过就直接使用会报错
    console.log(foo); // 输出undefined         先使用再声明,输出undefined(由var定义的变量)
    var foo = 2;
    foo = 2;
    console.log(foo); //2     此处没有报错,反而输出了2,是因为此处的foo没有由var声明,则被默认为window下的一个属性
    console.log(window.foo);//2

      暂时性死区:只要块级作用域内存在let命令(不管它的位置在前在后),它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响(外部是否定义过这个变量已经和这个区域无关了)。一旦在这个区域内,let声明不是在最前面,即先使用后才由let声明,则会报错。

    if (true) {
      // TDZ开始
      tmp = 'abc'; // ReferenceError
      console.log(tmp); // ReferenceError      //事实上,在代码执行的时候,如果报错了,会阻塞后面的语句执行,所以,把这两句注释掉,后面的语句才会正常执行
    
      let tmp; // TDZ结束
      console.log(tmp); // undefined
    
      tmp = 123;
      console.log(tmp); // 123
    }

      let不允许在相同作用域内,重复声明同一个变量。因此,不能在函数内部重新声明参数。

      2、块级作用域

      ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

      第一种场景,内层变量可能会覆盖外层变量。

      第二种场景,用来计数的循环变量泄露为全局变量,循环变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

      ES6 允许块级作用域的任意嵌套。

      外层作用域无法读取内层作用域的变量。

      内层作用域可以定义外层作用域的同名变量。

      块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)(即匿名函数自执行)不再必要了。(原意是为了不定义全局变量,所以放在一个匿名函数自执行里面)。

    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }

      3、const命令

      const声明一个只读的常量,在声明时,要立即初始化该变量,即给该变量赋值,否则会报错。由const声明的变量,一旦声明,其值就不能改变。

      在刚刚探讨的其他方面,const与let是相同的。

      本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针。如果真的想将对象冻结,应该使用Object.freeze方法。

    const foo = {};
    
    // 为 foo 添加一个属性,可以成功
    foo.prop = 123;
    foo.prop // 123
    
    // 将 foo 指向另一个对象,就会报错
    foo = {}; // TypeError: "foo" is read-only

      4、顶层对象的属性

      顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

    var a = 1;
    // 如果在 Node 的 REPL 环境,可以写成 global.a
    // 或者采用通用方法,写成 this.a
    window.a // 1
    
    let b = 1;
    window.b // undefined

      

      

      

      

      

  • 相关阅读:
    手机维修费杂乱 消协命令设立扶植行业标准
    ImageList控件的使用方法
    三峡实习记之一
    [原创]2天的搜索经验对IIS的问题的全面解决方案
    亲历虚拟机安装Ubuntu Linux系统
    新的一年,新的开始
    VS2003中实现身份验证的探索经验
    [原创]VS2003中ASP.NET实现自定义用户导航控件
    全面控制Windows任务栏
    单刀赴广州
  • 原文地址:https://www.cnblogs.com/chaoyueqi/p/7896426.html
Copyright © 2011-2022 走看看