ES6学习-module语法

Module语法

CommonJS模块

js 复制代码
let { readfile }  = require('fs')
# 等同于
let _fs = require('fs')
let readfile = _fs.readfile //这种加载称为"运行时加载"

ES6模块

js 复制代码
import { stat, exists, readFile } from 'fs';

这种加载称为"编译时加载"或者静态加载

静态加载带来的各种好处

  1. 效率要比 CommonJS 模块的加载方式高。
  2. 能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。
  3. 不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。
  4. 将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。
  5. 不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。

import()

import命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行

importexport命令只能在模块的顶层

这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块。在语法上,条件加载就不可能实现。

import()函数,支持动态加载模块。

运行时执行:也就是说,什么时候运行到这一句,就会加载指定的模块。

import()返回一个 Promise 对象。

js 复制代码
import('xxx')
.then(module => {module.default})

适用场合

  1. 按需加载
  2. 条件加载
js 复制代码
if(a) {import('xxx').then(({a,b,c}) =>{})}
  1. 动态的模块加载
js 复制代码
import(f())

import()也可以用在 async 函数之中。

严格模式

ES6 的模块自动采用严格模式

export 命令

export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

js 复制代码
// 报错
var m = 1;
export m;

因为没有提供对外的接口。直接输出 1。1只是一个值,不是接口。

export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错

因为处于条件代码块之中,就没法做静态优化了

import 命令

import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口。

import命令具有提升效果,会提升到整个模块的头部,首先执行。

js 复制代码
foo();
import { foo } from 'my_module';

上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。

由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

js 复制代码
// 报错
import { 'f' + 'oo' } from 'my_module';
// 报错
let module = 'my_module';
import { foo } from module;

import语句会执行所加载的模块,因此可以有下面的写法。

js 复制代码
import 'lodash';

多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。

js 复制代码
import 'lodash';
import 'lodash';
js 复制代码
import { foo } from 'my_module';
import { bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';

import在静态解析阶段执行,所以它是一个模块之中最早执行的。

js 复制代码
require('core-js/modules/es6.symbol');
require('core-js/modules/es6.promise');
import React from 'React';

模块的整体加载

js 复制代码
import * as circle from './circle';
console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));

export default 命令

export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。

js 复制代码
// 正确
var a = 1;
export default a;
// 错误
export default var a = 1;
// 正确
export default 42;
// 报错
export 42;

因为export default命令的本质是将后面的值,赋给default变量,所以可以直接将一个值写在export default之后。

如果想在一条import语句中,同时输入默认方法和其他接口,可以写成下面这样。

js 复制代码
import _, { each, forEach } from 'lodash';

export 与 import 的复合写法

js 复制代码
export { foo, bar } from 'my_module';

在一个模块之中,先输入后输出同一个模块

foobar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foobar

Module 的加载实现

没看

相关推荐
_Kayo_2 小时前
node.js 学习笔记3 HTTP
笔记·学习
加班是不可能的,除非双倍日工资4 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
CCCC13101635 小时前
嵌入式学习(day 28)线程
jvm·学习
gnip5 小时前
vite和webpack打包结构控制
前端·javascript
excel5 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
星星火柴9366 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头6 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼6 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin