ES6学习笔记(二十)ES Module的语法与使用

下面要写出的ES Module的语法,现在还无法在node直接执行,建议使用babel转码后执行(webpack配置babel执行ES module语法)
首先,在谈及ES module的语法前,要先明确一点,ES module默认使用严格模式
javascript严格模式整理,所以松散模式下的一些不会报错的地方在使用ES module时要注意

export


输出方式

1. 将整个声明输出

简单的变量

export var a = 1;

方法

export function fn(){
    // ...
}

export class c{
    // ...
}

2. 放在花括号内输出

var a = 1;
var b = 2;
export { a , b };
function fn(){
    // ...
}
export { fn };
class c{
    // ...
}
export { c };

3. as语法

ES module可以给输出的内容重命名,使用as来实现

var a = 1;
export { a as b };

注意点

命令所在

export命令可以写在当前模块顶层作用域的任何地方,写在块级作用域中会报错

if (true) {
    export var b = 2;
}

动态性

export命令输出的值是动态性的,在当前文件变量修改时,export输出的值也会随之变化

export var a = 1;
setTimeout(() => a = 2, 500);

上面这段代码,在500ms后输出的a的值会改变

import


输入方式

1. 花括号引入

import {…} from …

import { a } from 'xxx.js'
console.log(a);

花括号内的内容是其他模块export输出的内容,用as语法时是写 as 后的名称
from后面的路径可以是绝对路径,相对路径,或者是模块名

2. as语法

将引入的内容使用另一种别名,即等同于赋值给另一个变量

import { a as b } from 'xxx.js'

3. 导入整个模块

import ‘module’

注意点

sington

import命令是sington即单例模式的,多次引用只会被当作引用一次
(单例模式只在第一次引用时引用,后面的引用会直接使用之前引用的内容:JavaScript设计模式笔记(一)单例模式)

import { a } from 'xxx.js'
import { a } from 'xxx.js'

这里写了两句import语句,实际上只import了一次

import { a } from 'module.js'
import { b } from 'module.js'
// 等同于
import { a , b } from 'module.js'

上面代码中的这两种情况,在执行上是完全相同的,因为是引入同一个模块中的两个相同的变量

只读性

import命令引入的变量都是只读的,不能对其重新赋值,如果对import的变量进行赋值,则会报Syntax Error的错误

import { a } from 'xxx.js'
a = 2; // Syntax Error : 'a' is read-only

提升性

和var的变量声明提升一样,import引入的变量也会提升到整个模块的头部,被首先执行

console.log(a);
import { a } from 'xxx.js'

这里的a可以正常输出

静态执行

import是静态执行的,和require不一样,import是在编译的时候执行的,所以不能使用表达式和变量,也不能在块级作用域中使用
下面的代码都是错的

import { 'a'+'b' } from 'xxx.js'

let a = 'b';
import { a } from 'xxx.js'

if(true){
    import { b } from 'xxx.js'
}

这里的代码分别使用了拼接字符串,使用变量的值以及if-else语句,这些是在运行阶段执行的内容,在编译阶段不会执行这些内容,所以会报错

export default


输出语法

1. 声明后输出变量

var a = 1;
export default a;

2. 输出匿名函数

export default function(){
    // ...
}
// 输出非匿名函数也会被当作匿名函数
// 下面的输出对于import来说和上面的一样
export default function fn(){
    // ...
}

3. 放在花括号中输出

var a = 1;
var b = 2;
export default { a , b }

与export的不同

不能输出声明

使用export命令时,我们可以直接输出声明,但是使用export default时,不能输出声明

// 正确写法
export var a = 1;
var a = 1;
export default a;
// 错误写法
export default var a = 1;

import时能否修改变量名

直接使用export命令来输出内容,在import时必须知道export时输出的变量名或者函数名,类名,而使用export default时,在import的时候可以忽略输出时的变量名

// module.js
var a = 1
export { a }
// main.js
import { a } from './module.js'
// module.js
var a = 1
export default a
// main.js
import b from './module.js'

上面两段代码可以看出,使用export命令输出变量a,import的时候必须使用变量名a,而使用export default时不用使用同样的变量名,所以上面第二段代码import的时候可以使用b做为变量名

唯一性

export default只能使用一次,如同其名default默认,只能有一个默认的,而export是能够多次输出的

实质

export default实际上是将命令后面的内容赋值给一个变量default然后输出,所以可以通过使用export的as输出来达到同样的效果

export { a as default}
// 等同于
export default a

也正因为这样,所以我们不能在export default后面使用声明语句,因为我们不能将一个声明语句赋值给一个变量

在浏览器中的使用

现在在浏览器中,已经可以使用ES module的语法了
我们可以将script标签的type属性设置为module来使用ES module的语法,下面写个例子
根目录创建index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script type="module">
        import {a} from "./index.js"
        console.log("a",a)
    </script>
</body>

</html>

同样在根目录,创建一个index.js

export const a = 1

此时双击打开html文件,可能会报这样的错误
在这里插入图片描述
将这个错误翻译一下

加载模块脚本失败:服务器以非javascript MIME类型""响应。根据HTML规范,对模块脚本执行严格的MIME类型检查。

实际上,这是因为我们是在本地文件直接打开的,我们只要将它放在一个服务器下启动就可以了,使用vscode的话可以直接使用插件live server启动

启动后可以看到
在这里插入图片描述
控制台打印除了从index.js引用的a变量,然后我们再测试其动态性
index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script type="module">
        import {a} from "./index.js"
        setInterval(()=>{ console.log("a",a) },1000)
    </script>
</body>

</html>

index.js

export var a = 1
setInterval(() => {
    a++
}, 1000)

启动服务器打开页面,可以看到
在这里插入图片描述
动态性被成功验证



参考自阮一峰的《ECMAScript6入门》


ES6学习笔记(一)let和const
ES6学习笔记(二)参数的默认值和rest参数
ES6学习笔记(三)箭头函数简化数组函数的使用
ES6学习笔记(四)解构赋值
ES6学习笔记(五)Set结构和Map结构
ES6学习笔记(六)Iterator接口
ES6学习笔记(七)数组的扩展
ES6学习笔记(八)字符串的扩展
ES6学习笔记(九)数值的扩展
ES6学习笔记(十)对象的扩展
ES6学习笔记(十一)Symbol
ES6学习笔记(十二)Proxy代理
ES6学习笔记(十三)Reflect对象
ES6学习笔记(十四)Promise对象
ES6学习笔记(十五)Generator函数
ES6学习笔记(十六)asnyc函数
ES6学习笔记(十七)类class
ES6学习笔记(十八)尾调用优化
ES6学习笔记(十九)正则的扩展
ES6学习笔记(二十)ES Module的语法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值