es6模块化心得

前因

最近看了公司一位大佬的代码,突然对import()产生了疑问,并翻阅了一些资料进行查询,希望对同样有疑问的同学有一些帮助,也希望路过的大佬多多指教。接下来进入笔记分享~。

import函数

import()函数在ES2020提案 中引入,他可以异步动态加载模块,import()函数与所加载的模块没有静态连接关系,这点也是与import语句不相同之一。import函数的返回值是promise对象,可以使用.then.catch方法进行接收数据处理,import()加载模块成功以后,这个模块会作为一个对象,当作then方法的参数。因此,可以使用对象解构赋值的语法,获取输出接口。,其允许模块路径动态生成。import函数可以放在任何地方,因为它是运行时执行的,什么时候执行到它,就什么时候进行指定模块的加载,所以它可以在条件语句和函数中进行动态的加载,例如

if(true){
    return import('./xxx/aaa').then(msg=>{
        //加载内容  不会报错
    }).catch(err=>{
        //error codo
    })
}

由于它动态加载等特性,可以在一些场合很好的使用:

  1. vue项目路由按需加载
{
    path:'/xxx'
    name:'/XXX'
    component:()=>import(../xxx/xxx.vue)
    
}

2.模块的按需加载

xxx.click=function(){
    import('../xxx').then(fn=>{
        ...
    })
}

3.条件加载

if(true){
    return import('./xxx/aaa').then(msg=>{
        //加载内容
    }).catch(err=>{
        //error codo
    })
}

还可以配合promise的方法.all方法进行多个模块的加载,
还有很多的有趣用法这里就不一一列举了。

import语句

import语句是es6中提出的静态化的模块化思想的产物,与export配合使用,export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。在import和export都可以使用as关键字来为导出/导入的变量重新命名。例如:

./a.js
var chara=52
var charb=99
export {
    chara,
    charb as hhh
    charb as www
}
./b.js
import {chara as a,hhh,www as xxx} from ./a.js
//在文件中使用a,hhh,xxx

export语句输出的接口,与其对应的值是动态绑定关系,接口名与模块内部变量之间,建立了一一对应的关系。即通过该接口可以取到模块内部实时的值。export和import一样不可出现在块级作用域中,必须在顶层,导出的不可以为准确值必须是接口,且与ConmonJS不同的是,输出的接口不存在动态更新。
错误写法案例:

1.
var a = 3
export a //错误 ->相当于直接传了个3
正确:
export var a = 3 或者 var a = 3 export{ a }
2.
function fn(){}
export fn //错误
正确:
export function fn(){} 或者 function fn(){}  export { fn }  
其他同理

import命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,异步加载,只能放在模块首部,并不能支持条件语句,引擎处理import语句是在编译时,这时不会去分析或执行if等条件语句或者函数,所以import语句放在if等控制语句或函数代码块之中毫无意义,因此会报句法错误,而不是执行时错误。
例如:

if(true){
    import xxx from ./xxx; //报错
}

在使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,如果没去了解模块有哪些属性和方法,为了方便,就要用到export default命令,为模块指定默认输出(注意:在一个文件或模块中,export、import可以有多个,export default仅有一个)。例如:

//导出非匿名接口
function aa(){}
export default aa
或者
export default function aa(){} 

当export default导出匿名接口的时候,import会为这个匿名接口起任意的想要的名字。

//b.js
export default function(){}
//a.js
import xxx from ./b.js

export …from …
在一个模块中可以先导入再导出,例如:

export {a,b}from ./ab.js 
//也可以使用as,与合并前的区别在于a,b并没有导入当前模块,只是转发,使得当前模块不能使用a,b
//等同于:
import {a,b}  from ./ab.js
export {a,b}

默认导出和具名导出切换:

export { default as juming } from './defa'; //默认接口->具名接口
export { juming as default } from './defa'; //具名接口->默认接口
相当于:
import { juming } from './defa';
export default juming;

补充:

1.commonjs模块输出的是值的拷贝且具有缓存,运行时加载,在使用require时是进行同步加载,es6的模块化是在编译时输出接口,是异步加载,具有独立的模块依赖的解析阶段,在遇见import时,会生成一个只读引用,在脚本被执行的时候再到加载的模块内取值,因为只是导入是只读的,所以并不可以重新赋值。

2.es6模块简称ESM,commonjs模块的简称是CJS

3.commonjs已经实现es6模块的支持,但是需要一些设置,但是最好不要混用。

4.在es6模块时默认使用严格模式,所以不可以使用with和arguments,且顶层的this关键字之乡undefined。

import {xxx , xx} from '/xx.js’实质上并不是解构赋值。

5. import * as xx from '/xxx.js'->是生成了一个名为xx的对象,并将非默认导出的所有名字做为这个对象的属性。

6.细节使用export {xx,cc}和export defaule {}是不同的,

7.常识es6导入与函数声明类似,会被‘提升’到顶部,随时可以使用。

8.

<script type="module" src="./foo.js"></script>

设置type=“module”证明是es6模块,异步加载,到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性。

<script type="module" src="./foo.js"></script>
<!-- 等同于 -->
<script type="module" src="./foo.js" defer></script>

如果网页有多个<script type="module">,它们会按照在页面出现的顺序依次执行。

9.细节对于 import ‘./xx.js’.这样的模块在导入的时候会被运行一次,之后导入则不再运行,如果模块内定义了一些代码,即便没有到处也很有用。web应用可以使用分析模块,运行注册各种事件处理的代码,然后通过这些时间处理程序在合适的时机向服务器发送遥测数据,虽然是自包含的,不需要导出任何值,但是仍需要import导入才能让他成为程序的一部分运行,对这些有导出的模块也可以使用什么也不导入的语法。这种方式叫做 仅为副作用而导入一个模块,整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码, 但实际上不导入任何值

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值