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的语法

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值