首先,不管是在node中还是小程序中,我们在运行项目的时候,都会创建一个module空对象,以及一个exports,这个exports其实是module.exports的引用,什么是引用呢?就是指向了同一个地址,指向的地址内容改变时,他俩会同步的改变。但是最终导出的是module.exports这个对象,所以module.exports的指向一旦重新赋值,那么exports方法的导出将不再生效。
先看一个简单的引用例子
var a=1
b=a
这就是一个简单的引用,也可以理解为浅拷贝,a指向一个内存地址,然后b又指向a这个地址,这时候b就叫a的引用。
下面看具体例子,打印module和export可以看到
console.log(module) //得出
console.log(exports)
Module {
id: '.',
exports: {},
parent: null,
filename: 'e:\\syx\\test\\index.js',
loaded: false,
children: [],
paths:
[ 'e:\\syx\\test\\node_modules',
'e:\\syx\\node_modules',
'e:\\node_modules' ] }
{}
从打印的值可以看到module对象中有一个exports属性,我们在用module.exports.a=1这样赋值的时候,其实是改变了module的exports这个属性值,看下面打印结果:
module.exports.a=1
exports.b=2
console.log(module)
console.log(exports)
Module {
id: '.',
exports: { a: 1, b: 2 },
parent: null,
filename: 'e:\\syx\\test\\index.js',
loaded: false,
children: [],
paths:
[ 'e:\\syx\\test\\node_modules',
'e:\\syx\\node_modules',
'e:\\node_modules' ] }
{ a: 1, b: 2 }
这里为module.export添加了一个a的变量,可以看到exports的值也是变化了的,这也就说明了他俩指向同一个地址,但是我们知道导出的最终是module.exports,所以,一但module.exports的指向有了变化,那么exports添加的属性或者方法就不再生效了,看具体例子
module.exports.a=1
exports.b=2
console.log(exports == module.exports)
module.exports={c:3}
console.log(module)
console.log(exports)
console.log(exports == module.exports)
Module {
id: '.',
exports: {},
parent: null,
filename: 'e:\\syx\\test\\index.js',
loaded: false,
children: [],
paths:
[ 'e:\\syx\\test\\node_modules',
'e:\\syx\\node_modules',
'e:\\node_modules' ] }
{}
true
Module {
id: '.',
exports: { c: 3 },
parent: null,
filename: 'e:\\syx\\test\\index.js',
loaded: false,
children: [],
paths:
[ 'e:\\syx\\test\\node_modules',
'e:\\syx\\node_modules',
'e:\\node_modules' ] }
{ a: 1, b: 2 }
false
可以看到,在没有做module.exports={c:3}之前,module.exports=exports,而且他俩内存指向同一个地址,在改变了module.exports指向之后,这时候module.exports!=exports ,而且exports再也拿不到module.exports对象里面的内容,这就将导致在导出的时候,exports失效。
所以,在不改变module.exports的指向的时候,他俩其实都可以导出内容,但是一旦module.exports的指向改变,exports将不再有用。
那么module.exports exports 又和export export default什么关系呢?
module.exports exports是遵从commonjs的一种写法,这种用require引入模块来使用
export export default 是es6的写法,引用需要用import
export 命名导出
//a.js
export function getData(){
console.log('aaa')
}
//b.js
import {getData} from './a.js'
import {getData as get} from './a.js' //这里可以重命名
//对于重命名的导入的方法,直接使用重命名之后的名字
get() //aaa
export default 默认导出
不同于命名导出的是这种方法在一个页面只能使用一次,如果需要导出多个变量及方法,需要放在一起导出
//a.js
function getData(){
console.log('123')
}
export default{
a:'123',
getData
}
//b.js
import obj from './a.js' //这里obj是自己命名的 可以取里边的变量及方法
import {default as obj} from './a.js' //其实默认导出就相当于这样的命名导出
obj.getData() //123
混合导入
import React, {Component} from 'react'
注意:混合导入的默认导入必须在前边,命名导入在后边,否则会引起报错