Js模块化导入导出
Js模块化导入导出
CommonJs
、AMD
、CMD
、ES6
都是用于模块化定义中使用的规范,其为了规范化模块的引入与处理模块之间的依赖关系以及解决命名冲突问题,并使用模块化方案来使复杂系统分解为代码结构更合理,可维护性更高的可管理的模块。
CommonJS
CommonJS
是NodeJs
服务器端模块的规范,根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。CommonJS
规范规定,每个模块内部,module
变量代表当前模块。这个变量是一个对象,它的exports
属性是对外的接口。加载某个模块,其实是加载该模块exports
属性。总之,CommonJS
规范通过require
导入,module.exports
与exports
进行导出。
// 1.js
var a = 1;
var b = function(){
console.log(a);
}
module.exports = {
a: a,
b: b
}
/*
// 当导出的模块名与被导出的成员或方法重名时可以有如下写法
module.exports = {
a,
b
}
*/
// 2.js
var m1 = require("./1.js")
console.log(m1.a); // 1
m1.b(); // 1
也可以使用exports
进行导出,但一定不要重写exports
的指向,因为exports
只是一个指针并指向module.exports
的内存区域,即exports = module.exports = {}
,重写exports
则改变了指针指向将导致模块不能导出,简单来说exports
就是为写法提供了一个简便方案,最后其实都是利用module.exports
导出。此外若是在一个文件中同时使用module.exports
与exports
,则只会导出module.exports
的内容
// 1.js
var a = 1;
var b = function(){
console.log(a);
}
exports.a = a;
exports.b = b;
// exports = { a, b } // 不能这么写,这样就改变了exports的指向为一个新对象而不是module.exports
// 2.js
var m1 = require("./1.js")
console.log(m1.a); // 1
m1.b(); // 1
AMD
AMD
规范不是AMD YES
,AMD
异步模块定义,全称Asynchronous Module Definition
规范,是浏览器端的模块化解决方案,CommonJS
规范引入模块是同步加载的,这对服务端不是问题,因为其模块都存储在硬盘上,可以等待同步加载完成,但在浏览器中模块是通过网络加载的,若是同步阻塞等待模块加载完成,则可能会出现浏览器页面假死的情况,AMD
采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行,RequireJS
就是实现了AMD
规范。
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
// do something
});
define(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
// do something
return {};
});
/**
define和require在依赖处理和回调执行上都是一样的,不一样的地方是define的回调函数需要有return语句返回模块对象(注意是对象),这样define定义的模块才能被其他模块引用;require的回调函数不需要return语句,无法被别的模块引用
*/
// html的<script>标签也支持异步加载
// <script src="require.js" defer async="true" ></script> <!-- async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。 -->
CMD
CMD
通用模块定义,是SeaJS
在推广过程中对模块定义的规范化产出,也是浏览器端的模块化异步解决方案,CMD
和AMD
的区别主要在于:
- 对于依赖的模块,
AMD
是提前执行(相对定义的回调函数,AMD
加载器是提前将所有依赖加载并调用执行后再执行回调函数),CMD
是延迟执行(相对定义的回调函数,CMD
加载器是将所有依赖加载后执行回调函数,当执行到需要依赖模块的时候再执行调用加载的依赖项并返回到回调函数中),不过RequireJS
从2.0
开始,也改成可以延迟执行 -
AMD
是依赖前置(在定义模块的时候就要声明其依赖的模块),CMD
是依赖就近(只有在用到某个模块的时候再去require
——按需加载,即用即返)。
define(function(require,exports,module){
var a = reuire('require.js');
a.dosomething();
return {};
});
ES6
ES6
在语言标准的层面上实现了模块的功能,是为了成为浏览器和服务器通用的模块解决方案,ES6
标准使用export
与export default
来导出模块,使用import
导入模块。此外在浏览器环境中是可以使用require
来导入export
、export default
导出的模块的,但依然建议使用import
标准导入模块。
export
、export default
主要有以下区别:
-
export
能按需导入,export default
不行 -
export
可以有多个,export default
仅有一个 -
export
能直接导出变量表达式,export default
不行 -
export
方式导出,在导入时要加{}
,export default
则不需要
// 1.js
var a = 1;
var b = function(){
console.log(a);
}
var c = 3;
var d = a + c;
var obj = { a,b,c }
export {a,b};
export {c,d};
export default obj;
<!-- 3.html 由于浏览器限制,需要启动一个server服务 -->
<!DOCTYPE html>
<html>
<head>
<title>ES6</title>
</head>
<body>
</body>
<script type="module">
import {a,b} from "./1.js"; // 导入export
import m1 from "./1.js"; // 不加{}即导入export default
import {c} from "./1.js"; // 导入export 按需导入
console.log(a); // 1
console.log(b); // ƒ (){ console.log(a); }
console.log(m1); // {a: 1, c: 3, b: ƒ}
console.log(c); // 3
</script>
</html>
参考
https://segmentfault.com/a/1190000010426778
https://www.cnblogs.com/leftJS/p/11073481.html
https://www.cnblogs.com/zhoulujun/p/9415407.html
https://www.cnblogs.com/zhoulujun/p/9415407.html
https://www.cnblogs.com/moxiaowohuwei/p/8692359.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 浅谈matplotlib中FigureCanvasXAgg的用法
- Keras自定义实现带masking的meanpooling层方式
- 利用keras使用神经网络预测销量操作
- 获取python运行输出的数据并解析存为dataFrame实例
- 如何使用Cython对python代码进行加密
- PHP快速排序算法实现的原理及代码详解
- 从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
- keras实现VGG16 CIFAR10数据集方式
- PyTorch: Softmax多分类实战操作
- 为什么称python为胶水语言
- opencv 图像礼帽和图像黑帽的实现
- python文件及目录操作代码汇总
- 使用pyplot.matshow()函数添加绘图标题
- 如何卸载python插件
- Keras实现支持masking的Flatten层代码