1.12模块

概述

 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS(分别是基于 AMD 规范的模块化库,  和基于 CMD 规范的模块化库)。

ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量

ES6 的模块化分为导出(export) @与导入(import)两个模块

特点

ES6 的模块自动开启严格模式

模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等。

每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域

每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取


export 与 import

基本用法

  • import 命令会提升到整个模块的头部,首先执行

建议使用大括号指定所要输出的一组变量写在文档尾部,明确导出的接口。

函数与类都需要有对应的名称,导出文档尾部也避免了无对应名称

/*-----export [test.js] 导出模块
let myName = "Tom";
let myAge = 20;
let myfn = function(){
    return "My name is" + myName + "! I'm '" + myAge + "years old."
}
let myClass =  class myClass {
    static a = "yeah!";
}
export { myName, myAge, myfn, myClass }



 
/*-----import [xxx.js]引入模块
import { myName, myAge, myfn, myClass } from "./test.js";
console.log(myfn());// My name is Tom! I'm 20 years old.
console.log(myAge);// 20
console.log(myName);// Tom
console.log(myClass.a );// yeah!

as 的用法

不同模块导出接口名称命名重复, 使用 as 重新定义变量名

/*-----export [test.js]导出
let myName = "Tom";
export { myName as exportName }
 
/*-----import [xxx.js]导入
import { exportName } from "./test.js";
console.log(exportName);// Tom


使用 as 重新定义导出的接口名称,隐藏模块内部的变量
/*-----export [test1.js]导出
let myName = "Tom";
export { myName }
/*-----export [test2.js]导出
let myName = "Jerry";
export { myName }
/*-----import [xxx.js]导入
import { myName as name1 } from "./test1.js";
import { myName as name2 } from "./test2.js";
console.log(name1);// Tom
console.log(name2);// Jerry

import 命令的特点

只读属性:不允许在加载模块的脚本里面,改写接口的引用指向,即可以改写 import 变量类型为对象的属性值,不能改写 import 变量类型为基本类型的值。

import {a} from "./xxx.js"
a = {}; // error
 
import {a} from "./xxx.js"
a.foo = "hello"; // a = { foo : 'hello' }

单例模式多次重复执行同一句 import 语句,那么只会执行一次。import 同一模块,声明不同接口引用,会声明对应变量,但只执行一次 import 。

import { a } "./xxx.js";
import { a } "./xxx.js";
// 相当于 import { a } "./xxx.js";
 
import { a } from "./xxx.js";
import { b } from "./xxx.js";
// 相当于 import { a, b } from "./xxx.js";

静态执行特性:import 是静态执行,所以不能使用表达式和变量。

export default 命令

  • 在一个文件或模块中,export、import 可以有多个,export default 仅有一个
  • export default 中的 default 是对应的导出接口变量。
  • 通过 export 方式导出,在导入时要加{ },export default 则不需要
  • export default 向外暴露的成员,可以使用任意变量来接收。
var a = "My name is Tom!";
export default a; // 仅有一个
export default var c = "error"; 
// error,default 已经是对应的导出变量,不能跟着变量声明语句
 
import b from "./xxx.js"; // 不需要加{}, 使用任意变量接收

注意js:export 和 exports default的使用和区别 

export:一个文件可以有多个

同时在引入改文件时,可以使用解构的方式,直接获取到文件中 a、obj、add已经第一个导出的 对象中的属性

exports default:在同一个文件只有一个,且不能使用解构的方式获取对象中的属性,只能以一个对象导入,但是文件名可以自定义。


解读exports、module.exports 和 export、export default

exports 和 module.exports 是Node.js的模块系统关键字,

export 和 export default 则是 ES6模块系统的关键字。很明显,两者属于两个体系

require: node 和 es6 都支持的引入
export / import : 只有es6 支持的导出引入
module.exports / exports: 只有 node 支持的导出

导出模块exports=》导入使用时直接使用,不用new调用

//hello.js
var sayHello = function () {
    console.log('hello')
}
var sos = 110;
var app = {
    name: 'testApp',
    version: '1.0.0',
    help: function () {
        console.log('what can i do for you?')
    }
}

exports.sayHello = sayHello;

exports.sos = sos;

exports.app = app;

 或者是:

//hello.js
exports.sayHello = function () {
    console.log('hello')
}
exports.sos = 110;
exports.app = {
    name: 'testApp',
    version: '1.0.0',
    help: function () {
        console.log('what can i do for you?')
    }
}

 引入模块require

//main.js
var hello = require('./hello');

hello.sayHello();

console.log(hello.sos)
console.log(hello.app.version)

hello.app.help()

导出模块module.exports

把一个对象封装到模块中

//hello.js 
function Hello() {
    var name;
    var sos = '110';
    this.setName = function (thyName) {
        name = thyName;
    };
    this.sayHello = function () {
        console.log('Hello ' + name);
    };
    this.app = {
        name: 'testApp',
        version: '1.0.0',
        help: function () {
            console.log('what can i do for you?')
        }
    };
};
// 把变量、方法、JSON对象等封装在一起,一并导出
module.exports = Hello;

 引入模块=》需要new调用

通过new关键字,实例化一个hello模块的对象,通过这个对象才能调用hello模块相关的方法

//main.js
var Hello = require('./hello')
//通过new关键字,实例化一个hello模块的对象,通过这个对象才能调用hello模块相关的方法。
hello = new Hello();

hello.setName("zhangSan")
hello.sayHello()

console.log(hello.app.version)
hello.app.help()

exports模式下两者的异同

很明显!!! exports 和 module.exports 的内容是完全一样的,换言之:exports 指向的是 module.exports。

module.exports模式下两者的异同 

很明显!!!module.exports 模式下,module.exports 和 exports 的内容是完全不同的。

module.exports 导出的是模块(hello.js)对象本身(类别Java,可以理解为导出的是一个类,而不是实例化的对象)

在此场景下 exports 是空的(类比Java,理解为一个空对象,没有实例化就是null)

小结:输出的 module.exports 对象内容就是一个[Function],在 javascript 里面是一个类。使用这种方式的好处是: exports 只能对外暴露单个函数,但是 module.exports 却能暴露一个类。 

CommonJS 和 ES6

CommonJS

Node里面的模块系统遵循的是CommonJS规范,这个规范出来其实就是对模块的一个定义

CommonJS定义的模块分为:

模块标识(module)、模块定义(exports) 、模块引用(require)

node执行一个文件时,会给这个文件内生成一个 exports和module对象,而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域

 实际上,require导出的内容是module.exports的指向的内存块内容并不是exports的。简而言之,区分他们之间的区别就是 exports 只是 module.exports的引用,辅助后者添加内容用的。

注意:为了避免糊涂,尽量都用 module.exports 导出,然后用require导入

ES6

ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念。

在 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS(分别是基于 AMD 规范的模块化库, 和基于 CMD 规范的模块化库)。ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量。


js:export 和 exports default的使用和区别_龙雨LongYu12的博客-CSDN博客_exports default

一文解读exports、module.exports 和 export、export default_Jin_Kwok的博客-CSDN博客_module.exports 单例

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值