exports与module.exports的区分联系及用法,commonJS与ES6的模块化导入导出

exports与module.exports的区分联系及用法,commonJS与ES6的模块化导入导出

一、exports与module.exports的区分与联系

由下面代码及其输出值对比,可以得出3条结论:

1、module是一个对象,代表当前模块,其有一个属性exports(即module.exports)。

2、node.js为每一个模块提供了一个exports变量,有 exports = module.exports = {} ,即exports是module.exports的一个引用,两者指向同一个内存地址(值是一个空对象)。由于exports指向 module.exports, 所以exports.add = 5 相当于为module.exports.add = 5,即为其添加了一个属性 ;需要注意的是:不能把exports直接指向一个值,因为这样它就指向了一个新的内存地址(相当于断了module.exports 的关系)。

3、而且可以推测每个js文件在执行时可能默默做了以下两步操作: var module = new Module();var exports = module.exports; 所以才有 console.log(module) 不报错,exports == module.exports 且指向{}。 可以理解为module与exports是js文件的两个内置对象,初始时指向同一内存地址且值为空对象。

//demo.js

console.log(exports === module.exports)//true
console.log(exports)//{}
console.log(module.exports)//{}

//代码1
exports = 1;//直接赋值会改变指向,即指向新的内存地址
console.log(exports == module.exports)//false
console.log(exports)//1
console.log(module.exports)//{}
console.log(module)//Module{}

/*代码2
module.exports = {name:'qq'};//直接赋值会改变指向,即指向新的内存地址
console.log(exports == module.exports)//false
console.log(exports)//{}
console.log(module.exports)//{ name: 'qq' }
console.log(module)//Module{}
*/

输出值截图:
代码片段一的结果
代码片段二的结果
—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——

由以下代码可以得出 结论4:在引入时,require(’./xx.js’) 命令相当于读入并执行一个js文件,然后返回该模块的module.exports属性对象(在js文件末尾会默认有:return module.exports)。即module.exports是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

//demo.js
module.exports = '你是妖怪吧!'
exports = '是啊,你怎么知道?'


//text.js
var a = require('./demo.js')
console.log(a)//你是妖怪吧   因为module.exports指向新内存地址,值为 '你是妖怪吧',所以输出 '你是妖怪吧',和exports无关
//demo.js
exports = '来,快活!'


//text.js
var a = require('./demo.js')
console.log(a)//{}  因为module.exports值为{},所以输出{},和exports无关

当 module.exports 被赋值时即 (module.exports 指向新的内存地址时) ,exports 与 module.exports 的指向不再相同,若想让 exports 重新引用module.exports ,可以用 exports = module.exports = somethings 达成目的。

以上内容部分参考:https://www.jianshu.com/p/dd08f4095a49.

二、commonjs和ES6的导入和导出(使用)

1、commonjs:

导出:module.exports = a   exports.porp = a
        (a可以是数字、字符串、数组、对象、函数等)
导入:const n=require(‘x.js’)

module.exports 和 exports 的用法区别:
① module.exports 的用法:module.exports = a;
导出数字:

//demo.js
let a = 123;
module.exports = a;

//text.js
var app = require('./demo.js')
console.log(app)//123 

导出字符串:

//demo.js
let b = 'bbb';
module.exports = b;

//text.js
var app = require('./demo.js')
console.log(app)//bbb 

导出数组:

//demo.js
let c = [1,2,3];
module.exports = c;

//text.js
var app = require('./demo.js')
console.log(app)//[ 1, 2, 3 ]

导出函数:

//demo.js
let d = function(){
	console.log(222);
}
module.exports = d;

//text.js
var app = require('./demo.js')
console.log(app)//[Function: d]

导出对象:

//demo.js
var e = {
  	age:18,
 	sayName: function(name){
        console.log(name+'---'+this.age);
   	}
}
module.exports = e;

//text.js
var app = require('./demo.js')
console.log(app)//{ age: 18, sayName: [Function: sayName] }

② exports 的用法 exports.app=a;
导出数字:

//demo.js
let a = 123;
exports.num = a;

//text.js
var app = require('./demo.js')
console.log(app)//{ num: 123 }

导出字符串:

//demo.js
let b = 'bbb';
exports.str = b;

//text.js
var app = require('./demo.js')
console.log(app)//{ str: 'bbb' } 

导出数组:

//demo.js
let c = [1,2,3];
exports.arr = c;

//text.js
var app = require('./demo.js')
console.log(app)//{ arr: [ 1, 2, 3 ] }

导出函数:

//demo.js
let d = function(){
	console.log(222);
}
exports.fun = d;

//text.js
var app = require('./demo.js')
console.log(app)//{ fun: [Function: d] }

导出对象:

//demo.js
var e = {
  	age:18,
 	sayName: function(name){
        console.log(name+'---'+this.age);
   	}
}
exports.obj = e;

//text.js
var app = require('./demo.js')
console.log(app)//{ obj: { age: 18, sayName: [Function: sayName] } }

    对比发现,在导出同样的内容时 module.exports 导出的是值,exports导出的是以导出时携带的参数为键名,值为值的对象。
    由于exports与module.exports指向同一内存地址,所以在使用时:exports.app == module.exports.app

commonJS补充内容:

//demo.js
let a = 123;
let b = 'bbb';
let c = [1,2,3];

module.exports = {a,b,c}


//text.js
var app = require('./demo.js')
console.log(app)//{ a: 123, b: 'bbb', c: [ 1, 2, 3 ] }
/*或者:
var {a,b,c} = require('./demo.js')
console.log(b)//bbb
*/
//demo.js
let a = 123;
let b = 'bbb';
let c = [1,2,3];

exports.num = a;
exports.str = b;
exports.arr = c;


//text.js
var app = require('./demo.js')
console.log(app)//{ num: 123, str: 'bbb', arr: [ 1, 2, 3 ] }

2、ES6:

导出:export | export default
①以 export 方式导出:导入方式:import {n} from xx.js ,并且导出和导入的变量名必须一样。如果导出的数据较多,在导入时可以以 import * as sj from xx.js 形式导入,使用:sj.导出变量名
②以 export default 方式导出:导入方式:import n from xx.js ,导出的变量名可以和导入的不一样,自己命名。但是,export default 使用有限制(只能在导出一个数据时使用,否则导入时不知道导出的是哪一个)
把引入的js文件模块化(有自己作用域),加上 type=‘module’,如:<script src='' type='module'></script> 此时,引入的js文件就不是全局的了(有了自己的作用域,不能再全局访问),别的文件如果要使用需要 import 导入。

注意:
    可以 export const age = 10 ;
    但是不可以 const age = 10;export age;会报错:Uncaught SyntaxError: Unexpected token ‘export’。若想先定义后导出,必须放在{}中,如 const age = 10;export {age}

es6演示:(由于nodeJS不配置不能使用ES6相关导入导出,所以放在浏览器演示)

//text.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>es6导入导出</title>
	</head>
	<body>
		<script src='./b.js' type='module'></script>
		<!--需要注意的是:type='module'不能少,否则会报错:不能在模块外部使用import语句(导入导出都是针对模块而言的)-->
	</body>
</html>
//a,js
function fn(prop1,prop2){
	console.log(prop1**prop2)//求幂
}
let age = 5
export let name = 'jj'	
export {				
	fn,age
}

let hobbies = '唱跳rap篮球'
export default hobbies
//b.js
/* 方式1:
import * as prop from './a.js'
console.log(prop.name)
console.log(prop.age)
prop.fn(2,5) 
*/

//方式2:
import {name,age,fn} from './a.js'
console.log(name)
console.log(age)
fn(2,7) 

//方式3:
import h from './a.js'	//h 自己命名,代表hobbies
console.log(h)

//方式1和2适用于export形式导出,方式3适用于export default方式导出

//结果展示
演示结果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值