zoukankan      html  css  js  c++  java
  • ES6(一) let和const

      随着前端技术的逐渐强大,JavaScript从一个简单的脚本语言,迅速的伸出了它的触角,一直延伸到了后端。于是原有的ES3/ES5的语法与规范已经不能适应它的发展了,因此w3c就在2015年推出了js新的语法规范,也就是ECMAScript6,也叫ECMAScript2015,一般简称为ES6。

     一、let

      在ES3和ES5中,JS只有全局作用域和函数作用域,它是没有块级作用域的。任何时候声明变量都是使用var关键字。

      在ES6支持了块级作用域的概念,支撑这个块级作用域的新语法就是新增了let关键字,用来取代var,作为声明具有块级作用域的变量的关键字。

      let本身是很简单,只有几个需要注意的点。

      1.越界访问会报错,而不是输出undefined

    1 function test(){
    2     for (let i = 0; i < 5; i++) {
    3        console.log(i);
    4     }
    5     console.log(i);//报错
    6 }
    7 test();

      这个demo的输出结果如下面的截图

      。  

      本身例子很简单,循环输出0-4,并且在for循环结束后再次访问循环变量i,由于i是用let声明的,这个i就是个块级作用域。第5行代码试图访问i,但是已经超出了i的作用域范围。所以报错。

      但是这里有个疑问,为什么第5行是报错,而不是undefined?

      原因如下:

      1.如果js代码中使用了ES6语法规范,那么该执行环境就是默认的开启了“严格模式”

      2.所谓严格模式,在ES5的时代,就是在你的js代码中,写入了‘use strict’这样的字符串。‘use strict’可以理解为一个指令,它告诉浏览器,我之后的js代码,都要以严格模式的规范来解析。而在ES6中,不需要声明这个指令,就默认使用了严格模式

      3.在严格模式中,如果变量没有声明就拿来使用,就会报”引用异常“的错误:ReferenceError。而不会是undefined。

      2.在一个块之内,不允许重复定义  

    function test(){
        let num = 10;
        let num = 20;
    }
    test();

      这个例子的执行结果如下图:

      

      这里报的错是,num重复定义了。

      如果使用var声明变量,是不会报错的,后声明的num会把之前声明的num给覆盖了。

      但是使用let就不行了,重复定义变量会报错的。  

      3.没有变量提升    

    console.log(a);
    var a = 10; // undefined
    console.log(b);
    let b = 20; // 报错:Uncaught ReferenceError: b is not defined

      4.暂时性死区  

    var num = 10;
    if(true){
        console.log(num);  // 输出10
        var num = 20;
    }

      这个例子我们没有使用let关键字声明变量,所以这里很显然输出的就是10。再来看下面的变化  

    var num = 10;
    if(true){
        console.log(num);  // 报错:Uncaught ReferenceError: num is not defined
        let num = 20;
    }

      在此例里,我们在if语句块中使用了let来声明变量,则输出语句就报错了。原因是只要使用了let声明变量,就会产生所谓“暂时性死区”的现象;说白了就是,num是用let声明的变量,在其所在的块级作用域之内num就被锁定了,它不能访问代码块外部声明的同名变量。

      以上就是let与var的区别。非常简单,其实习惯了强类型语言的朋友,压根就不会觉得有什么奇怪的,早该如此。。。。

      二、const

      const也是ES6新增的关键字,它是用来声明常量的。与其他语言中的常量一样,const声明的常量,只能在声明时赋值,并且不能重复赋值。它有如下几个需要注意的点。

      1.只能在声明时赋值,所以下面的例子会报错的。  

    function test(){   
        const stu;   
        stu = '张明';   
        console.log(stu);
    }

      报错,在使用const声明常量的时候,没有赋值。

      2.const声明的常量也是一个具有块级作用域的。不能跨作用域访问。

    function test(){
        {
            const stu = '张明';
            console.log(stu); //输出 '张明'
        }
        console.log(stu); //报错,stu超出了作用域
    }

      这个例子执行时会报stu未声明的错误,原因就是stu是在一对{ }中声明的,于是它的作用域仅限于这个花括号之内。在外部访问stu,虽然它贵为常量,也无法跨作用域访问。

      3.值类型的常量不能二次赋值,但是引用类型的对象,有特例。比如下面的例子。

     1 function test(){
     2     const stu = '老张';
     3     // stu = '老王'; //报错
     4     console.log(stu);
     5     const student = {age: 18};
     6     student.age = 20; //不会报错
     7     student.name = '小赵'; //不会报错
     8     student = { id: '1800123', age: 18}; //报错
     9     console.log(student.age);
    10 }

      分析:

      1.在第2行声明的stu是一个string类型常量,它是个值类型的,所以如果执行第3行代码,就会报错。

      2.在第5行,声明的student是一个对象,它是引用类型的。所以执行第6、7行代码都不会报错。

      3.但是如果执行第8行代码,就会报错。

      原因是student是1个对象,它是应用类型的,它本身只存了1个地址作为引用,const要求不能二次赋值,第6行和第7行,虽然改变了student所指向的对象的属性,但是并没有改变student作为引用类型变量它本身所存储的那个地址的指向。换句话说,并没有改变student这个常量存储的值。所以第6、7行不会报错。

      反而是第8行,又拿了1个新的字面量对象给student赋值,这就改变了student引用的地址,也就改变了student存储值,所以会报错。

      这个一定要注意。

  • 相关阅读:
    为什么股票一买就跌,一卖就涨?终于找到答案了!
    搜集的一些股票讲师的博客
    一位操盘手的临别赠言
    VMware网络连接 桥接、NAt、host-only模式
    我常用的网络测试工具
    linux下性能测试工具netperf使用
    vm10虚拟机安装Mac OS X10.10教程
    ACE_Svc_Handler 通信原理
    mypwd实现
    2019-2020-1 20175307 20175308 20175319 实验五 通讯协议设计
  • 原文地址:https://www.cnblogs.com/ldq678/p/10325378.html
Copyright © 2011-2022 走看看