ES6中声明变量的方法以及export和import

106 阅读6分钟

    1.let和var的区别以及const

           ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。文字说明很难理解,直接上代码。

        

  {
        let a = 20// 在块作用域中定义变量 a
        var b = 1// b 是函数/全局作用域,整个 script 都能访问
        
  }
     console.log('b', b)// 输出:b 1
    // console.log(' a', a)//  报错:a is not defined(块作用域外无法访问 a)
    console.log('b', b)// 这句不会执行!因为上面报错了,程序中断了

         这里我们可以看到在作用域外面我们是拿不到a的,输出就会报错,而且之后的js代码无法执行,但是如果我们没有定义全局变量b,而是在输出b之后用 var 定义b这个变量。控制台会输出什么呢?

        

//  console.log(v)
    // var v =6
    //会等价为
    // var v
    // log(v) --undefined

        当我们在用var 定义变量之前输出v,会自动帮我们声明一下v这个变量,可能是觉得我们忘记了?控制台输出undefined。这显然是不符合逻辑的,我们没有声明直接输出undefined,也就是用var会触发变量提升。

        这时候第一个区别就出现了。let const 如果没有声明直接输出就会进入暂时性死区,

也就是不会默认帮我们声明,而是直接报错停止整个js逻辑不会往后执行代码。不会出现变量提升。

        第二个区别就是作用域。let只能在当前的作用域中去使用,收到{}限制,但是var使用的时候会被当作全局变量。

        

 // 理解 var 和 let 的作用域区别:
    // var
     作用域是 函数级,不受 {} 块限制
    // 所以 var b = 1 虽然写在 {} 内,但它 仍然存在于整个 <script> 作用域内
    // let
    // 作用域是 块级,受 {} 限制
     let a = 20 只在 {} 块内部有效,外部访问会报错
     for (let i = 0; i < 10; i++) {

     }
     console.log(' i', i)
    //这里i是undefined 报错
     var a = []
    for (var i = 0; i < 10; i++) {
         a[i] = function () {
             console.log('i', i)
        }
        }
     a[0]()
     a[5]()
     a[6]()
    //     那么当 for 循环执行完毕时:
    // i = 10(因为 0910 次)

    // 所有的函数 都“共享”这一个 i

    // 它们不是“记住了那个时刻的 i”,而是“用的时候才看 i 是多少”
     var a = []
    for (let i = 0; i < 10; i++) {
         a[i] = function () {
             console.log('i', i)
         }
     }
     a[0]()----0

          当我们用var去执行for循环的时候,每次循环i的值改变,这时候i是全局变量,所以循环完之后i的值是10,那么所有的函数都会共享这一个全局变量10.

        但是当我们有let的时候,我们这里i只在循环这个作用域定义使用,但是我们却在for循环执行的js代码中定义了一个函数调用了i,也就是我们在let i这个作用域创建了一个函数或者箭头函数,用到了变量i,就会形成一个闭包。捕获到变量,那么即使作用域结束了,函数也能记住定义时外部作用域的变量。

        

        // 第一次循环

        // let i = 0 // 创建一个新的作用域(Scope A),i=0

        // a[0] = function() { console.log(i) } // 在 Scope A 里定义这个函数,i=0被“绑定”

        // // 第二次循环

        // let i = 1 // 创建一个新的作用域(Scope B),i=1

        // a[1] = function() { console.log(i) } // i=1 被“锁定”在这个函数作用域中

        // 使用 let 的 for 循环中,每次循环都会创建一个新的块级作用域,i 被“独立封装”,所以每个函数都记住了当时的 i。

        所有当我们输出a0的时候值为0。

        

 for (let i = 0; i < 3; i++) {
        let i = 'abc'
        console.log(' i', i)
    }
    console.log(' i', i)
    //     for (let i = 0; ...) 中的 i,定义在 for 循环自己的作用域中(这是一个块级作用域);

    // 循环体 { let i = 'abc' } 又定义了 另一个同名变量 i,它遮蔽(shadow)了外层的 i;

    // 所以它们完全没关系,是两个不同作用域的变量。

        这里for循环(){}是两个作用域所以两个i只是同名但实际不是一个同一个变量,所以里面输出abc,外面是报错。

        


     function func() {
         let a = 1
         var a = 10
     }
    //let 不允许重复声明同一个变量在同一个作用域中
     function func() {
         let a = 1
         let a = 10
     }
     

        这里都会报错,不可以重复声明同一个变量在同一个作用域中。

       const 声明的变量不得改变值,一旦声明变量,必须初始化而且和let一样只在声明的块级作用域有效。const 声明的变量如果是数组或者对象,那么保证地址不变的情况下可以给他们合并更新新的属性或者元素。但是不能改变地址,因为保存的只是指向对象或者数组的指针,只要指针也就是地址不变。对象本身是可以改变的也就是更新函数是可以更新合并新属性的。

2.export和import

        ES6提出了export和import规范,背景是js可以实现模块化,模块化开发的本质是把一个复杂的系统按照功能拆分多个小文件(模块),每个模块只做一个事情,开发效率高,复用性强,避免命名冲突,方便协作和维护。

        Es6核心设计思路是 每个js文件就是一个模块可以导出自己的变量,函数,类等供其他模块使用

        import引入的模块是只读引用,可以修改传进来对象的属性,修改数组的元素,变量重命名但是不可以给变量重新赋值。

        ​编辑

        这是es6export的方法使用,默认导出以及统一导出。

​编辑

        es6引入的方法

        ​编辑        这是入口文件,所有的模块汇总到这里,还可以用定时器,或者异步函数去动态引入。

        ​编辑

        在html文件要声明我们引入的js类型是module,这样我们引入的模块js就会被隔离,模块里面的所有数据只是在模块里面的作用域声明定义,比如我们在控制台输出模块里面的函数,是报错找不到的。而且引入的所有值我们都当作常量不可以更改重新赋值。