您现在的位置是:首页 >学无止境 >Module的语法, JS中的 export 和 import网站首页学无止境

Module的语法, JS中的 export 和 import

weixin_49035434 2023-07-16 12:00:02
简介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 }

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。