资讯专栏INFORMATION COLUMN

js导入导出总结与实践

yanwei / 1448人阅读

摘要:在上一篇文章中中和模块的导入导出对比,偏向于理论层面,还有一些同学在微信群里或是私下里针对一些问题进行了沟通,所以有了这一篇文章,对的导入导出进行总结和实践当直接给时,会失效这个问题其实已经和导入导出没什么关系了,我们看一个知乎上的问题详细

在上一篇文章中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 数组赋值问题 :值传递还是引用?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109279.html

相关文章

  • JavaScript中AMD和ES6模块的导入导出对比

    摘要:每个模块内部,变量代表当前模块。这个变量是一个对象,它的属性即是对外的接口。加载某个模块,其实是加载该模块的属性。为了方便,为每个模块提供一个变量,指向。这等同在每个模块头部,有一行这样的命令。 我们前端在开发过程中经常会遇到导入导出功能,在导入时,有时候是require,有时候是import在导出时,有时候是exports,module.exports,有时候是export,expo...

    刘明 评论0 收藏0
  • 阿里HBase的数据管道设施实践演进

    摘要:摘要第九届中国数据库技术大会,阿里巴巴技术专家孟庆义对阿里的数据管道设施实践与演进进行了讲解。它必须在把风险做完,风控是根据长期的历史信息近期历史的信息和实时的信息三个方向做综合考量。 摘要:第九届中国数据库技术大会,阿里巴巴技术专家孟庆义对阿里HBase的数据管道设施实践与演进进行了讲解。主要从数据导入场景、 HBase Bulkload功能、HImporter系统、数据导出场景、H...

    LMou 评论0 收藏0
  • 你可能不熟悉的JS总结

    摘要:在语法上,称为暂时性死区。唯一的缺点可能就是浏览器兼容性不太好了。 暂时性死区 只要块级作用域存在let命令,它所声明的变量就绑定这个区域,不再受外部的影响。这么说可能有些抽象,举个例子: var temp = 123; if(true) { console.log(temp); let temp; } 结果: > ReferenceError: temp is no...

    LiveVideoStack 评论0 收藏0
  • docker 镜像容器的导入导出操作实践

    摘要:二思路我一开始想的是把镜像文件直接拷贝到测试服务器对应的目录,不过在查找相关资料发现本身就提供了导入和导出的功能,因此到这个过程到简单了,导出和导入的功能中也分了镜像与容器的概念。 一、背景 公司有一台测试服务器,网速比较慢,特别是下载一些国外站点镜像的时候,而我本机则比较快,还有梯子,所以在思考一个问题;是否能在我本地把镜像下载下来,然后复制到测试服务器中。 二、思路 我一开始想的是...

    huayeluoliuhen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<