美文网首页
ES模块语法学习小记

ES模块语法学习小记

作者: zhaochengqi | 来源:发表于2018-09-12 08:45 被阅读61次

    原文:http://es6.ruanyifeng.com/#docs/module

    ES6模块是静态加载的(编译时加载),在编译时就可以确定模块的输入输出和模块间的依赖关系。
    ES6模块自动采用严格模式

    一个模块就是一个独立的文件。文件内部的所有变量外部无法访问。如果希望允许外部访问模块内部某个变量,需要使用export命令输出该变量。

    #1. export 命令

    export命令用于规定模块的对外接口(暴露哪些变量)

    #1.1 输出变量、函数和类

    //frank.js 写法一
    export var name = 'FrankZ';
    export var age = 25;
    export function work(x, y) {return x + y};
    
    //frank.js 写法二
    var name = 'FrankZ';
    var age = 25;
    function work(x, y) {return x + y};
    export {name,age, work}; 
    

    这两种写法是等价的,建议使用后者,输出了哪些变量清晰明了。

    注意export {name,age, work}; ,不要把{name,age, work}当成对象,这只是ES6规定的暴露接口的语法形式。

    #1.2 重命名

    var a = {x: 1};
    var b = {x: 2};
    export {
        a as c,
        b as d,
        b as e
    };
    

    通常export输出的变量就是本来的名字,但可以使用as关键字重命名。只有export {...}这种形式才可以重命名

    上面代码重命名了对外接口a、b,这样a,b,c,d都被暴露出去了。引用时,a和c、b和d都指向同一个对象

    其中b被重命名了两次。

    #1.3 export命令规定的是对外接口,必须与模块内部变量一一对应

    //错误写法
    export 1; //报错,1只是一个值,没有提供对外接口(外部不晓得用哪个变量名来访问1)
    var m = 1;
    export m; //报错,同上
    
    //正确写法
    var m = 1;
    export {m} // 正确写法,规定了对外接口m;{m}不是对象
    export var m = 1; // 正确写法,应该算是上面写法的简写吧
    

    #1.4 TIPS

    • export命令输出的接口与其对应的值是动态绑定关系,通过接口可以取到模块内部实时的值
    • export命令可以出现在模块任何位置(但必须是顶层,即不能处于块级作用域中)

    #2. import命令

    import命令用于加载模块,导入模块输出的变量。

    #2.1 import命令接受一对大括号,from指定模块文件的位置

    import {name, age, work} from './frank'
    

    #2.2 import命令可以使用as关键字重命名导入的变量

    import {name as uid} from './frank'
    

    不同于export命令,这里如果访问name将会报错 【ReferenceError: name is undefined】

    #2.3 import命令会执行所加载的模块,因此也可以选择不导入接口

    import 'lodash'
    

    #2.4 整体加载

    import * as frank from './frank';
    

    上面代码使用星号(*)指定了一个对象frank,所有输出值都挂在这个对象上面。

    需要注意的是挂载到frank的各项属性仍然是只读的。

    #2.5 Tips

    • 大括号里面指定要导入的变量名(必须与被导入模块对外接口的名称相同)
    • 文件位置可以是相对路径也可以是绝对路径,.js后缀可以省略。如果只是模块名不带路径,那么必须有配置文件
    • import命令具有提升效果,会提升到某块头部首先执行
    • import是静态执行,所以不能使用表达式和变量
    • 如果多次重复执行同一句import语句,那么只会执行一次;多次加载同一个模块只会得到同一个模块实例(单例模式)
    import 'lodash';
    import 'lodash';
    import 'lodash'; // 只会执行一次
    
    import {name} from './frank'
    import {age} from './frank'
    //等同于
    import {name, age} from './frank'
    

    #3 MORE

    #3.1 export default 命令

    var g = 1
    export default g
    //
    export default g = 1
    //
    export default function(){} // 导出匿名函数,import引入后function name属性为default
    //
    export default function test(){} // 导出匿名函数,import引入后function name属性为test
    
    import anything from './frank' // 只有当目标模块有default输出时才可以这样引入; 如果只有默认输出,import不能加大括号
    

    本质上export default命令就是输出一个叫做default的变量或方法,然后允许在引用的时候指定任意名字

    //
    export default var g = 1 // 错误, 原因如上所述
    //
    export default a
    //等同于
    export {a as default}
    
    export default 100 // 正确
    

    Tips

    • export default命令用于指定模块的默认输出,那么很显然一个模块只能有一个默认输出。
    • 如果想在一条import语句中同时导入默认接口和其他接口,可以写成下面这样:
      import def, {a, b, c} from './frank'
      

    #3.2 export & import 复合写法

    当一个模块需要导入并导出同一个模块,import和export语句可以写在一起

    export {a, b} from './frank' 
    // 写成一行后,a, b 实际上并没有被导入当前模块,不能直接使用a和b;只是相当于对外转发了这两个接口
    
    export {a as c, b} from './frank'
    //趁机改个名字
    
    export {default} from './frank' 
    export {default as sth} from './frank' 
    //默认接口
    
    export * from './frank'
    
    //暂不支持以下三种
    import * as si from ''
    import si from ''
    import si, {si2} from ''
    

    #3.3 模块的继承

    export * from 'superModule' //export * 命令会忽略导入模块的default变量
    export default 'subModule'
    

    相关文章

      网友评论

          本文标题:ES模块语法学习小记

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