您现在的位置是:首页 >学无止境 >Module的语法, JS中的 export 和 import网站首页学无止境
Module的语法, JS中的 export 和 import
在ES6之前, 社区制定了一些模块加载方案, 最主要的有CommonJS和AMD两种. 前者用于服务器,后者, 用于浏览器
ES6模块的设计思想是尽量静态化, 使得编译时就能确定模块的依赖关系
ES6模块不是对象, 而是通过export命令显示指定输出的代码,再通过import命令输入.
// ES6模块
import { stat, exists, readFile } from 'fs' 
上面代码的实质是从fs模块加载3个方法, 而不加载其他方法. 这种加载成为"编译时加载"或"静态加载', 即ES6可以在编译时就完成模块加载
注意:
在ES6模块中, 顶层的this指向undefined, 不应该在顶层代码中使用this.
export 命令
export 命令用于规定模块的对外接口.
一个模块就是一个独立的文件, 这个文件内部的所有变量,外部无法获取. 如果希望外部能够读取模块内部的某个变量,就必须使用export 关键字输出该变量.
// 下面js文件使用export输出变量
    // profile.js
    export var firstName = 'wei'
    export var lastName = '健力宝'
    export var year = '1958'
    // 与前一种写法是等价的, 优先考虑这种写法. 可以再脚本尾部一眼看清楚输出哪些变量
    var firstName = 'wei'
    var lastName = '健力宝'
    var year = '1958'    
    export {
        firstName,
        lastName,
        year
    }
    // 除了输出变量,还可以输出函数或class
    export function multiply(x,y){
        return x * y
    }
    
     
使用as关键字重命名
    function v1() { ... }
    function v2() { ... }
        
    export {
        v1 as streamV1,
        v2 as streamV2,
        v2 as streamLatestVersion
    }
    // 上面代码使用as关键字重命名了函数v1和v2的对外接口,重命名后v2可以用不同的名字输出
 
export 命令规定的是对外的接口, 必须与模块内部的变量建立一一对应的关系
// 报错
export 1
// 报错
var m = 1
export m
// 上面两种写法都会报错, 因为没有提供对外的接口. 
// 第一种写法直接输出1, 第二种写法通过变量m依然直接输出1. 1只是一个值, 不是接口
// 正确写法
// 写法1
export var m = 1
// 写法2
var m = 1
export { m }
// 写法3
var n = 1
export { n as m}
 
// 以上三种都是正确的, 规定了对外的接口m. 其他脚本通过这个接口取得值1. 
// 它们的实质是, 在接口名与模块内部变量之间建立一一对应. 
export 语句输出的接口与其对应的值是动态绑定关系, 通过该接口可以渠道模块内部实时的值
export var foo  = 'bar'
setTimeout(() => foo = 'baz', 5000)
// 上面代码输出变量foo, 值为bar, 5000ms之后变成baz.
// 这一点和CommonJS不同, CommonJS模块输出的是值的缓存.
 
最后, export命令可以出现在模块的任意位置,只要处于模块顶端就可以. 如果处于块级作用域内, 就会报错.
function  foo () {
    export default 'bar'
}
foo()
// 报错 
 
import 命令
使用export 命令定义了模块的对外接口后, 其他js文件可以通过import命令加载这个模块.
    // main.js
    import { firstName, lastName, year } from './profile'
    
    // from指定的位置可以是相对位置也可以是绝对位置.
    /*
        import 命令用于加载profile.js文件 import命令接受一个对象,里面指定要从其他
        模块导入的变量名, 大括号中的变量必须与被导入模块对外接口的名称相同.
    */ 
如果要为输入的变量重新取一个名字,要在import 命令中使用as关键字
import { firstName as surname } from './profile' 
import 命令具有提升效果, 会提升整个模块的头部并首先执行
foo()
import { foo } from 'module'
// 不会报错, 因为import的执行早于foo的调用
// 本质是,import命令是在编译阶段执行的,在代码运行之前 
 
模块的整体加载
除了指定加载某个输出值, 还可以整体加载(星号*)来指定一个对象.
    // circle.js
    export function area(radius) {
        return Math.PI * radius * radius
    }
    export function circumference(radius) {
        return 2 * Math.PI * radius
    }
    // main.js
    import { area, circumference }  from './circle'
    console.log('圆面积', area(4) );
    console.log('圆周长', circumference(14) )
    // 整体加载的写法
    import * as circle from './circle'
    console.log('圆面积', circle.area(4) );
    console.log('圆周长', circle.circumference(14) );
 
 
export default 命令
export default 命令为模块指定默认输出
// export-default.js
export default function() {  // 默认输出是一个函数
    console.log('foo')
}
// import-default.js
import customName from './export-default'
customName() // 输出foo
//上面的import命令可以用任意名称指向export-default输出的方法.这时import不需要大括号
// export default用在非匿名函数也是可以的
export default function foo() {  
    console.log('foo')
}
import foo from 'foo'
// 对应的import语句不需要使用大括号
// 或者写成
function foo() {
    console.log('foo')
}
export foo
// 需要使用大括号 
本质上, export default 就是输出一个叫做default的变量或方法, 然后系统允许我们为它取任意名字.
export和import的复合写法
如果在一个模块中先输入后输出同一个模块,import语句可以与export语句写在一起.
export { foo, bar } from 'module'
//等同于
import { foo, bar } from 'module'
export { foo, bar } 
 
                
            




U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结