zoukankan      html  css  js  c++  java
  • ECMAScript6-let和const命令

    ▓▓▓▓▓▓ 大致介绍

      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); //undefined
            var a = '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入门-阮一峰

  • 相关阅读:
    【机器学习】算法原理详细推导与实现(一):线性回归
    《0~3岁孩子的 正面管教》——备忘
    马歇尔·卢森堡《非暴力沟通》——备忘
    李笑来《财富自由之路》——备忘
    select、poll、epoll之间的区别总结[整理]
    堆和栈区别
    Linux 文件系统剖析
    Inside The C++ Object Model(五)
    Inside The C++ Object Model(四)
    Inside The C++ Object Model(三)
  • 原文地址:https://www.cnblogs.com/qqandfqr/p/6627145.html
Copyright © 2011-2022 走看看