Node: module.exports require
Node应用由模块组成,采用Commonjs模块规范。根据这个规范,每个文件就是一个模块,有自己的作用域。在这些文件里面定义的变量、函数、类,都是私有的,对外不可见,因此规避掉了作用域污染。
根据Commonjs规定,每个模块内部,module变量代表当前模块,这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实就是加载该模块的exports属性。
举例:
let a = "just a string"
let b = function(){
console.log("just another string")
}
module.exports.a = a;
module.exports.b = b;
require:用于加载模块
var all = require("a.js");
console.log(all.a) // just a string
all.b() // just another string
exports 与 module.exports
为了方便,node为每个模块提供了一个exports变量,指向module.exports。这等同于在每个模块头部,有这么一行代码:
var exports = module.exports
我们可以直接在exports对象上添加方法(等同于在 module.exports 添加一样)
let a = "just a string"
let b = function(){
console.log("just another string")
}
exports.a = a;
exports.b = b;
P.S.不能直接将exports指向一个值,这会切断 exports 与 module.exports 的联系(但是可以用module.exports来指向一个值)
ES6: export import
export导出的模块,需要用import引入,而不能用require。
export命令规定的是对外的接口,必须与模块内部的变量建立对应关系。
const a = 'just a string';
// 有三种方法可以导出
// 第一种
export var b = a;
// 引用:
import { b } from "a.js"
// 第二种
export { a }
// 引用:
import { a } from "a.js"
// 第三种
export { a as b }
// 引用:
import { b } from "a.js"
// 引用的时候也可以指定别名如:
import { b as c } from "a.js"
export 和 export default
1.export 和export default 均可用于导出(常量 | 函数 | 文件 | 模块)等。
2.可以在其他文件中通过 import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够进行使用。
3.在一个文件或者模块中,export、import 可以有多个,但 export default 仅有一个。
const a = 'just a string'
const b = 'another string'
export { a }
export { b }
// 引用
4.通过 export 方式导出,在导入时要用花括号{ };而通过 export default 方式导出的,则不需要:
const a = 'just a string'
export default a
// 引入
import a from "a.js"
import *
将一个js文件中定义的方法,模块,对象等,全部导出,一般结合别名使用,如:
const a = 'just a string'
const b = 'another string'
export { a }
export { b }
// 引入
import * as all from "a.js"
all.a
all.b
如果用export default导出,然后用import * 引入
const a = 'just a string'
export default a
// 引入
import * as all from "a.js"
all.default.a
##补充
1.本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。
import { default as all } from "a.js"
all.a
2. export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
// a.js
export let a = 'just a string';
setTimeout(() => a= 'change to another string', 500);
// main.js
import { a } from "a.js"
console.log(a); // just a string
setTimeout(()=> console.log(a),2000)
console.log(a); // change to another string
3. export 和 import 命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,这是因为处于条件代码块之中,就没法做静态优化了,违背了 ES6 模块的设计初衷。
4. import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口。
5. import命令具有提升效果,会提升到整个模块的头部,首先执行。
6. 由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。
7. import语句会执行所加载的模块,因此可以有下面的写法。
8. 目前阶段,通过 Babel 转码,Commonjs 模块的require命令和 ES6 模块的import命令,可以写在同一个模块里面,但是最好不要这样做。因为import在静态解析阶段执行,所以它是一个模块之中最早执行的。
9. 如果想在一条import语句中,同时输入默认方法和其他接口,可以写成下面这样。
import _, { each, forEach } from 'lodash';
10. export default也可以用来输出类。
// MyClass.js
export default class { ... }
// main.js
import MyClass from 'MyClass';
let o = new MyClass();
11. export 与 import 的复合写法
export { a, b } from "a.js"
需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foo和bar。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。