js导入导出总结与实践

3次阅读

共计 4834 个字符,预计需要花费 13 分钟才能阅读完成。

在上一篇文章中 JavaScript 中 AMD 和 ES6 模块的导入导出对比,偏向于理论层面,还有一些同学在微信群里或是私下里针对一些问题进行了沟通,所以有了这一篇文章,对 js 的导入导出进行总结和实践
当直接给 module.exports 时,exports 会失效
这个问题其实已经和导入导出没什么关系了,我们看一个知乎上的问题(详细地址阅读原文可以查看)我们以此为突破点 js 数组赋值问题:值传递还是引用?
var a = [1,2,3];
var b = a;
a = [4,5,6];
console.log(b); //=>[1,2,3]
继续看
var a = [1,2,3];
var b = a;
a.pop();
console.log(b); //=>[1,2]
为什么会出现这种情况?
数组和对象的赋值操作都是引用传递
看下这个(留意注释部分)
var a = [1,2,3];// a 指向了数组 [1,2,3];
var b = a;//b 指向 a 所指向的数组 [1,2,3];
a = [4,5,6];//a 指向了新的数组 [4,5,6],(a 的指向发生了变化,改变的是 a 引用本身,没有改变数组对象, 所以 b 没有变)
console.log(b); // b 没有改变,还是指向数组 [1,2,3];
再看下这个(留意注释部分)
var a = [1,2,3];// a 指向了数组 [1,2,3];
var b = a;//b 指向 a 所指向的数组 [1,2,3];
a.pop();// a 指向的数组实例发生了 pop 操作
console.log(b); //=>a 和 b 都是指向同一个数组,a 变量,所以 b 也变量,最后输出 =>[1,2]
看一张图片,很形象的描述数组如此,对象也是大同小异看一个群友 @ZSing 提供的 demo
var test = {
“name”: “zhangshuo”
}
var demo = test;

demo.name = “want you”
// 你认为 test 是什么?
console.log(test)//=>{name: ‘want you’}
下面通过注释解释一下(如出一辙)
var test = {“name”: “zhangshuo”}//test 指向了一个对象 {“name”: “zhangshuo”}
var demo = test;//demo 指向 test 所指向的对象 {“name”: “zhangshuo”}
demo.name = “want you”// 对象的属性发生了改变 {“name”: “want you”}
// 你认为 test 是什么?
console.log(test)//=>{name: ‘want you’}
test 和 demo 指向了同一个对象,一个变了,就都变了同样的,我们对上面的 demo 做一下改造
var test = {
“name”: “zhangshuo”
}
var demo = test;
test={
“name”: “ 更改了这个 name”
}
demo.name = “want you”
// 你认为 test 是什么?
console.log(test)//=>{name: ‘ 更改了这个 name’}
还需要对此进行赘述吗?还是通过注释对此进行解释说明
var test = {“name”: “zhangshuo”}//test 指向了一个对象 {“name”: “zhangshuo”}
var demo = test;//demo 指向 test 所指向的对象 {“name”: “zhangshuo”}
test={“name”: “ 更改了这个 name”}//test 的指向发生了变化,指向了一个新对象 {“name”: “ 更改了这个 name”}
demo.name = “want you”//demo 的指向没有变,改变了原对象的属性 {“name”: “want you”}
// 你认为 test 是什么?
console.log(test)//=>{name: ‘ 更改了这个 name’}
我相信,上面的两个栗子你已经看懂了,即将进入正题先来一个过渡再看一个栗子,用来模拟 exports 和 module.exports 的关联关系
let md = {exps:{}}//md 指向一个对象 {exps:{}}
let exps = md.exps//exps 指向了 md.exps 所指向的对象 , 这个空对象 {}
md.exps = {a: 1, b: 2}//md.exps 指向了一个新对象 {a: 1, b: 2}
exps.c=3//exps, 属性赋值 {c: 3}
console.log(md.exps); // 新对象 {a: 1, b: 2}
上面栗子中的 md 就是 module,md.exps 就是 module.exports,exps 就是 exports 在每一个模块的头部都有一行这样的命令
var exports = module.exports;
当直接给 module.exports 赋值时(module.exports={…..}),module.exports 就指向了一个新对象,exports 会失效
直接给 exports 赋值会切断 exports 和 module.exports 的关联关系
还是这样的一个前提
var exports = module.exports;
exports 是来自于 module,exports 指向 module.exports 所指向的对象当直接给 exports 赋值,即
exports = {a:1}
exports 指向了一个新对象,不再是 module.exports 所指向的对象,所以不要给 exports 直接赋值(exports =。。。)
实践 => 导出
exports
exports 的 output.js
exports.str=’string 字符串 ’// 导出字符串
exports.bool=true// 导出布尔
exports.num=123// 导出 number
exports.foo=(r)=>{// 导出函数
console.log(` 导出函数为:${r}`);
}
exports.arr=[1,2,3]// 导出数组
exports.obj={a:1, b:2}// 导出对象
input.js
const iptObj= require(‘./output.js’)
console.log(iptObj.str);//=>string 字符串
console.log(iptObj.bool);//=>true
console.log(iptObj.num);//=>123
console.log(iptObj.arr);//=>[1, 2, 3]
console.log(iptObj.obj);//=>{a: 1, b: 2}
iptObj.foo(‘ 参数 ’)//=> 导出函数为:参数
module.exports
module.exports 的 output.js
module.exports={
str:’string 字符串 ’,
bool:true,
num:123,
foo:(r)=>{
console.log(` 导出函数为:${r}`);
},
arr:[1,2,3],
obj:{a:1, b:2}
}
input.js
const iptObj= require(‘./output.js’)
console.log(iptObj.str);//=>string 字符串
console.log(iptObj.bool);//=>true
console.log(iptObj.num);//=>123
console.log(iptObj.arr);//=>[1, 2, 3]
console.log(iptObj.obj);//=>{a: 1, b: 2}
iptObj.foo(‘ 参数 ’)//=> 导出函数为:参数
module.exports 的 output.js 同时支持如下写法
module.exports.str=’string 字符串 ’
module.exports.bool=true
module.exports.num=123
module.exports.foo=(r)=>{
console.log(` 导出函数为:${r}`);
}
module.exports.arr=[1,2,3]
module.exports.obj={a:1, b:2}
input.js 不变
export
export 的 output.js
export const srt = ‘string 字符串 ’
export const bool = true
export const num = 123
export const arr = [1, 2, 3]
export const obj = {a: 1, b: 2}
export function foo(r) {
console.log(` 导出函数为:${r}`);
}
input.js
import {str,arr,obj,bool,num,foo} from ‘./output’
console.log(str)
console.log(arr)
console.log(obj)
console.log(bool)
console.log(num)
foo(‘ 参数 ’)
export 的 output.js 同时支持如下写法
const str = ‘string 字符串 ’
const bool = true
const num = 123
const arr = [1, 2, 3]
const obj = {a: 1, b: 2}
function foo(r) {
console.log(` 导出函数为:${r}`);
}
export {
str,bool,num,arr,obj,foo
}
input.js 导入支持重命名
import {str as STR,arr,obj,bool,num,foo as FOO} from ‘./output’
console.log(STR)
console.log(arr)
console.log(obj)
console.log(bool)
console.log(num)
FOO(‘ 参数 ’)
继续重命名
import * as newName from ‘./output’
console.log(newName.str)
console.log(newName.arr)
console.log(newName.obj)
console.log(newName.bool)
console.log(newName.num)
newName.foo(‘ 参数 ’)
export default
export default 的 output.js
export default {
str: ‘string 字符串 ’,
bool: true,
num: 123,
foo: (r) => {
console.log(` 导出函数为:${r}`);
},
arr: [1, 2, 3],
obj: {a: 1, b: 2}
}
input.js
import defaultObj from ‘./output’
console.log(defaultObj.str)
console.log(defaultObj.arr)
console.log(defaultObj.bool)
console.log(defaultObj.num)
console.log(defaultObj.obj)
defaultObj.foo(‘ef’)//=> 导出函数为:ef
export default 的 output.js 同时支持如下写法
const str = ‘string 字符串 ’
const bool = true
const num = 123
const arr = [1, 2, 3]
const obj = {a: 1, b: 2}
function foo(r) {
console.log(` 导出函数为:${r}`);
}
export default {
str,
bool,
num,
arr,
obj,
foo
}
input.js 不变
总结
这篇文章是对上一篇文章的总结和实践

当直接给 module.exports 时,exports 会失效
直接给 exports 赋值会切断 exports 和 module.exports 的关联关系
export,export default,exports,module.exports 具体的使用方法实例

更多前端资源请关注微信公众号“前端陌上寒”
原文链接
参考链接 js 数组赋值问题:值传递还是引用?

正文完
 0