美文网首页
ECMAScript6-let和const命令

ECMAScript6-let和const命令

作者: 老板丶鱼丸粗面 | 来源:发表于2017-03-27 16:31 被阅读0次

    大致介绍
    ES6是下一代的JavaScript语言的标准,目标是让JavaScript可以用来编写大型的复杂程序,成为企业级开发语言,要查看浏览器对ES6的支持程度可以用阮一峰大佬写的工具ES-Checker
    安装:(需要安装npm(心累),推荐用cnpm)
    npm install -g es-checker
    es-checker
    效果(有具体的支持情况):


    let
    let命令,和var的作用一样,都是用来声明变量,只是let命令只在所在的代码块内有效
    经典的例子:

    var a = [];
    for(var i=0;i<10;i++){
    a[i] = function(){
    console.log(i);
    }
    }
    a[4](); //10
    console.log(i); //10
    

    经典的例子,就不赘述,这里a数组都是引用的同一个i
    改用 let:

    var a = [];
    for(let i=0;i<10;i++){
    a[i] = function(){
    console.log(i);
    }
    }
    a[4](); //4
    console.log(i); // ReferenceError: i is not defined
    

    这里i用let声明,就只在本次循环中存在,每次循环都会创建一个i
    注意:在for循环中,循环语句是一个作用域,而循环体内部又是一个子作用域
    例如:

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

    可以看出循环体内的i和循环语句中的i是分离的
    let的特点
    1、不存在变量提升

    console.log(a);//undefinedvara = '123';
    console.log(b);
    let b= '123';//ReferenceError: b is not defined
    

    2、暂时性死区
    如果在一个块级作用域内有let命令,那他声明的变量就绑定这个块级作用域,不受外部的影响

    var a = '123';
    if(true){
    a = '456';
    console.log(a); //ReferenceError: a is not defined
    let a;
    console.log(a); //undefined
    }
    

    ES6明确规定,如果区块中存在let或者const命令,这个区块对这些命令声明的变量,从一开始就形成封闭作用域,凡是在声明之前使用这些变量都会报错
    这里a是用let声明的,所以在let声明之前使用a都会报错
    3、不能重复声明
    let不允许在同一个作用域内,声明同一个变量

    //报错
    {
    var a = '123';
    let a = '456';
    }
    //报错
    {
    let a = '123';
    var a = '456';
    }
    //报错
    {
    let a = '123';
    let a = '123';
    }
    

    注意:在函数内不能重复声明参数

    //报错
    function test(target) {
    let target;
    }
    //不报错
    function test(target){
    {
    let target;
    }
    }
    

    在第二个函数里不报错,是应为{}中时一个新的子作用域,和参数target不是在同一个块内了
    块级作用域
    let为JavaScript新增了块级作用域
    使用var是没有块作用域概念的

    var a = '123';
    if(true){
    var a = '456';
    }
    console.log(a); //456
    

    使用let就有了块作用域

    let a = '123';
    if(true){
    let a = '456';
    }
    console.log(a); //123
    

    外层的代码块不受内层代码块的影响
    块级作用域和函数声明
    ES5规定函数只能在顶层作用域和函数作用域中声明,不能在块作用域中声明
    ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
    例如:

    function f(){
    console.log('out');
    }
    (function(){
    if(false){
    function f(){
    console.log('in')
    };
    };
    f();
    }());
    

    在ES5中结果是 'in'。就是函数声明提升,不在多赘述
    在ES6中,理想的结果是'out',但是在浏览器中运行时,却会报错,这是为什么?因为如果这么突兀,那么老的代码就会出现很多的问题,所以,ES6规定浏览器可以有自己的的行为方式
    1、允许在块级作用域内声明函数。
    2、函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    3、同时,函数声明还会提升到所在的块级作用域的头部。
    注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。
    在ES6中实际执行的代码是

    function f(){
    console.log('out');
    }
    (function(){
    var f = undefined;
    if(false){
    function f(){
    console.log('in')
    };
    };
    f();
    }());
    

    注意:ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

    // 不报错
    'use strict';
    if (true) {
    function f() {}
    }
    // 报错
    'use strict';
    if (true)
    function f() {}
    

    const命令
    const声明一个只读的常量,一旦声明,常量的值就不能改变。所以在使用const时,一旦声明就要立即初始化
    const和let一样,只存在与本块作用域中,没有声明提升,存在暂时性死区,不可重复声明
    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
    例如:

    const a = {
    id: 1,
    name:'qqqq'
    };
    a.id = 2;
    a = {}; //报错
    

    参考资料:
    ECMAScript 6入门-阮一峰
    博客地址:www.cnblogs.com/qqandfqr

    相关文章

      网友评论

          本文标题:ECMAScript6-let和const命令

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