记录--你真的能区分JavaScript的各种导入导出方式吗?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
前言
我们在无论是在查阅别人的代码,还是在实际项目开发的过程中,肯定都会使用导入导出的功能,有时候我们会搞混这几种方式到底有什么区别,今天我们就来细致的区分一下:
导入导出方式⚔️⚔️
我们都知道最常见的几种导出方式无非是export,exports,export default,module.exports这几种,常见的导入方式则就是import和require,那么他们到底有什么区别呢?我们一起来看一下:
最为新手小白的我们在看到第一眼的时候肯定会一脸懵,其实我们可以将他们根据不同的JavaScript规范来分开来看
export和export default
export和export default是ES6的规范:
这两种方式其实没有什么本质的区别,我们一起来看一下示例:
使用export default这种导出方式叫做默认导出(暴露)
var name = "小明";
var fun = function () {
console.log(name);
};
export default { name, fun };
-----------------------
export default function() {
console.log ('export 不能这样子')
}
这里我们可以看到我们声明了一个函数,里面打印了变量name的值,然后我们使用export default导出了一个函数对象,也可以直接默认的导出一个函数。
值得注意的是,在一个js文件中只能有一个export default,不能重复的书写,否则会报错,而我们在接收这个导出的对象的中的内容的时候我们需要使用import来进行导入。
几个容易错误的点:
export default const name3 = 'error'; //这样导出的方式是错误的
-----------------------
var name3="小红";
export default name3;//这样是正确的
当然接收导出的值的时候也需要注意
import接收导出的值:
我们在使用export default导出的时候我们在接受值的时候需要注意
import text from "app.js"
我们假设需要导出内容的是app.js这个文件,我们在接收的时候可以自己定义一个变量名称,就像示例中的test,当然如果想要获取导出对象中的内容就可以使用解构的语法。这一点与export是有区别的
export导出示例:
var age=20; var open=true;
export {age,open} //等同于下边
export {age}
export {open}
export const fun=()=>{console.log("hhh")}
export const age1 = 23 //let 也行
在export中我们可以一口气导出多个变量或者对象,函数等而且我们也可以向最后一行代码那样在导出的时候定义变量名称,有一点需要注意使用export导出的内容必须有名称,就比如导出函数的时候不能像默认暴露那样直接导出一个匿名函数。
导入时的注意点:
import {age,open} from "app.js"
import {fun} from "app.js"
import {age1 as age2} form "app.js"
这里要注意我们在导入的时候一定要加上花括号,而且花括号中的名称必须和导出的变量或者函数名称一样,这一点时与export default不同的,还有我们导入在age1可以将其重命名为age2.
module.export 和exports
首先这两种方式是基于Common.js的规范来定义的,而这个规范是在Node.js中,因此这两种方式主要是在Node.js中使用
在上下文中提供了exports对象用于导出当前模块的方法或者变量,他是唯一导出的出口,当然在模块中还存在module对象,他代表模块自身,exports就是module的属性(默认的值是一个空对象),而在Node.js中一个文件就是一个模块,所以我们导出
在模块之中上下文提供require来引入外部的模块,
首先我们先来查看module.exports这种方式。
const a = 1;
const fun = () => {
console.log(2);
};
module.exports = { a, fun };
var req = require ('../app.js');
console.log(req.a1,req.a)
//1 [Function: fun]
我们在导出的时候需要注意导出的先后循序,当然这也可以当作面试出题,比如一下这几行代码导出的先后顺序不一样就会打印出不同的值,我们可以一起来看一下:
const a = 1;
const fun = () => {
console.log(2);
};
// console.log(fun);
module.exports.a2 = 4;
module.exports = { a, fun };
const req = require("./module.exports");
console.log(req.a, req.fun, req.a2);
//1 [Function: fun] undefined
为什么会有undefined呢?
我们在开始的时候说了我们其实发通过exports这中方式默认是导出一个空的对象,所以我们通过module.exports.a2这种方式导出其实是在这个空的对象上面添加了一个a2属性并且值为4,但是下来通过module.exports导出的时候,我们通过赋值的方式将之前的对象给覆盖了,因此之前的a2值就没有了,
同样如果我们给这两种导出的方式换一下先后顺序,比如我们这样写
module.exports = { a, fun };
module.exports.a2 = 4;
我们就可以获取到a2的值,因为我们先进行了对象的覆盖,然后在新对象上面增加了一个a2的属性并且值为4。
exports导出
其实exports 是module.exports的一个引用,可以认为是 var exports = module.exports
我们来讲解一下他们二者的区别:
直接赋值和替换对象的行为不同:
module.exports = value;:将module.exports直接赋值为一个新的值,这个新值会成为模块的导出内容。例如:module.exports = { a: 1 };,地址发生了改变直接替换之前的所有内容。exports.key = value;:将一个新的属性和值添加到exports对象中。例如:exports.a = 1;
module.exports优先级高于exports:- 如果在模块中同时使用
module.exports和exports,那么最终导出的内容以module.exports为准。也就是说,exports对象的变化不会影响最终导出的内容。
- 如果在模块中同时使用
使用exports的误区
直接上一个例子来给大家演示一下:
const a = 1;
const fun = () => {
console.log(2);
};
exports.a3 = { a, fun };
const req = require("./module.exports");
console.log(req);
console.log(req.a, req.fun);
//{}
//undefined undefined
为什么会出现这种情况呢?
我们知道在最初的时候module.exports和exports最初是指向同一个对象,也就是他们的地址是相同的,但是在这里我们通过对象给exports赋值的时候实际上已经改变了exports的地址,但是module.exports还是默认的地址指向还是一个空的对象,而我们执行导出的时候实际上还是通过module.exports,所以最终还是导出了一个空对象。
因此我们在module.exports和exports混用的时候要注意地址的问题,不要直接改变module.exports的地址,如果直接改变了,那么exports的操作就会不生效,如果你想混用,那最好全部用module.exports.x = xxx和exports.xx = xxxx这种写法,这样的写法就没有改变默认的地址。
exports.a2 = 4;
module.exports.fun = fun;
module.exports.a = a;
--------------------
const req = require("./module.exports");
console.log(req);
//{ a2: 4, fun: [Function: fun], a: 1 }
本文转载于:
https://juejin.cn/post/7241111319591452729
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--你真的能区分JavaScript的各种导入导出方式吗?的更多相关文章
- MySQL问题记录——导入导出权限设置
MySQL问题记录——导入导出权限设置 摘要:本文主要记录了在使用MySQL的过程中导入导出权限设置时遇到的问题以及解决方案. 相关日志 [Note] --secure-file-priv is se ...
- JavaScript Array 对象方法 以及 如何区分javascript中的toString()、toLocaleString()、valueOf()方法
1.concat() 2.join() 3.pop() 4.push() 5.reverse() 6.shift() 7.unshift() 8.slice() 9.sort() 10.splice( ...
- 我想这次我真的理解了 JavaScript 的单线程机制
今天面试的时候被问到一个问题,是关于 JS 异步的.当时我脑海中闪过了一个单线程的概念,但却没有把真正的原理阐述清楚.所以回来特意重新回顾了前面单线程和异步相关的一些知识点. 虽然之前学习的时候也接触 ...
- JavaScript动态加载script方式引用百度地图API 拓展---JavaScript的Promise
上一篇博客JavaScript动态加载script方式引用百度地图API,Uncaught ReferenceError: BMap is not defined 这篇文章中我接触到一个新的单词:Pr ...
- mysql数据库导入导出 查询 修改表记录
mysql数据导入导出: 导入: 把系统的文件的内容,保存到数据库的表里 导入数据的基本格式:mysql> load data infile "文件名" into table ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- JavaScript的3种继承方式
JavaScript的继承方式有多种,这里列举3种,分别是原型继承.类继承以及混合继承. 1.原型继承 优点:既继承了父类的模板,又继承了父类的原型对象: 缺点:不是子类实例传参,而是需要通过父类实例 ...
- javascript模块导入导出
第一次知道javascript有模块的概念通常都是使用<script>标签进行引入,不过只能在html文件上使用 增加的模块就如同php里的include.require可以使用引入的内容 ...
- 【转】SVG与HTML、JavaScript的三种调用方式
原文:https://www.cnblogs.com/guohu/p/5085045.html SVG与HTML.JavaScript的三种调用方式 一.在HTMl中访问SVG的DOM 1 2 3 4 ...
- 你真的搞懂ES6模块的导入导出规则了吗
前言 模块作为ES6规范的核心部分之一,在实际项目开发中经常会看到它的身影,那么我们是否真正了解它的相关规则呢,今天就带大家一起了解一下模块的导入导出规则 导入 ES6模块的导入(即import)大致 ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (198)-- 算法导论14.3 6题
六.用go语言,说明如何来维护一个支持操作MIN-GAP的一些数的动态集Q,使得该操作能给出Q中两个最接近的数之间的差值.例如,Q=(1,5,9,15,18,22),则MIN-GAP返回18-15=3 ...
- 机器学习基础01DAY
数据的特征抽取 现实世界中多数特征都不是连续变量,比如分类.文字.图像等,为了对非连续变量做特征表述,需要对这些特征做数学化表述,因此就用到了特征提取. sklearn.feature_extract ...
- 华为云GaussDB支撑农行超级网银业务,性能和稳定性备受认可
数据库作为数据驱动业务创新和智慧银行建设的关键基础设施,在银行数字化变革中具有举足轻重的作用. 在金融科技发展和国家政策引领下,银行纷纷加快推进数字化转型时代,正在经历一场以科技引领.数据赋能.数字经 ...
- NC20667 数学题
题目链接 题目 题目描述 最近,华东交通大学ACM训练基地的老阿姨被一个数学问题困扰了很久,她希望你能够帮她解决这个问题. 这个数学问题是这样的,给你一个N,要求你计算 gcd(a,b)表示a和b的最 ...
- python中矩阵切片维数微秒变化
1 前言 使用切片访问矩阵的部分数据(特别是一行或一列数据)时,通常会出现切片维数怎么在瞎变化,以致于不得不用reshape()强制改变维数.在深度学习中,网络对矩阵维数的要求是非常严格的,往往就是这 ...
- Laravel入坑指南(11)——列队
很高兴,我们来到了Laravel入坑指南的第11篇.这一系列的文章已经接近尾声了,在这一节里面,我们一起讨论列队的用法. 列队,顾名思义,将需要处理的任务一个一个排好队,等待处理程序来处理.这机的列队 ...
- ElasticSearch入门安装与SpringBoot集成实战
介绍 Elasticsearch 是一个实时分布式搜索和分析引擎,一般用于全文搜索.结构化搜索,分析或者三者混用. 它的底层是基于Apache Lucene(TM)的开源搜索引擎,但是lucene只是 ...
- Springboot实现remember-me记住我功能
1.什么是remeber-me? remeber-me即记住我功能,是我们在登录web系统时的常见勾选项.当我们登录一个web系统时除了输入常规的用户名.密码后还可以勾选记住我选项(假设该系统提供了该 ...
- LayUI框架应用常见问题
https://layui.itze.cn/index.html LayUI框架文档主页 获取URL参数 诸如表格中的"编辑","详情"工具按钮,需要在弹出层页 ...
- JAVA 考试管理系统 大作业(一):需求分析
好家伙,有需要的拿去借鉴吧(虽然我也百度了很多) 题目如下: 题目四:考试管理系统 (选做要求:使用图形用户界面) 分3种用户角色:教务员(具有管理权限).教师.学生 l 教务员:可以进行用户管理( ...
