require 动态加载_require,exports,module.exports和import,export,export default

我们前端在开发过程中经常会遇到导入导出功能,

在导入时,有时候是require,有时候是import

在导出时,有时候是exports,module.exports,有时候是export,export default

今天我们对这些内容进行简单的介绍

import,export,export default

import,export,export default属于ES6规范

import

import 是在编译过程中执行 也就是说是在代码执行前执行,

比如说,import后面的路径写错了,在运行代码前就会抛错,

在编写代码时,import不是一定要写在js的最前面

import命令具有提升效果,会提升到整个模块的头部,首先执行。(是在编译阶段执行的) import是静态执行的 因为import是静态执行的,不能使用表达式和变量,即在运行时才能拿到结果的语法结构

比如,不能再if和else中使用import

再比如,import后的from的路径,可以是相对路径,可以是绝对路径,但是不能是根据变量得来的路径

//import 路径不可以为变量

var url = './output'

  import {

    a,

    b

  } from url//这么写会报错

//------------------

//import 的引入与否不能和代码逻辑向关联

let status= true

if(status){

     import {

    a,

    b

  } from url//这么写会报错

}

import可以使用as进行重命名

import 的有很多种导入方式,

  import foo from './output'

  import {b as B} from './output'

  import * as OBj from './output'

  import {a} from './output'

  import {b as BB} from './output'

  import c, {d} from './output'

导入的方式和导出有些关联,我们在下面说导出的时候,对以上这些导入方式进行逐一介绍

exoprt和export default

将exoprt和export default放在一起,因为它们关联性很大

简单说:export是导出,export default是默认导出

一个模块可以有多个export,但是只能有一个export default,export default可以和多个export共存

export default 为默认导出,导出的是用{}包裹的一个对象,以键值对的形式存在

导出的方式不同,导入的方式也就不同,

所以建议同一个项目下使用同一的导入导出方式,方便开发

export default解构以后就是export

通过两个直观的demo看下export和export default的区别

先看一段代码(export) 

output.js

const a = 'valueA1'

export {a}

input.js

import {a} from './output.js'//此处的import {a}和export {a},两个a是一一对应关系

console.log(a)//=>valueA1

留意上面的代码其中export {a}导出的a,和import {a}导入的a是同一个a

再看一段代码(export default)

const a = 'valueA1'

export default{a}

input.js

import a from './output.js'//此处的a和export default{a},不是一个a,

console.log(a)//=>{ a: 'valueA1' }

看下export default的栗子中的input.js,我们稍作改动

import abc from './output.js'//此处的a和export default{a},不是一个a,

console.log(abc)//=>{ a: 'valueA1' }

我们做了些改动,但是输出没有变化,import导入的是export default下的对象,叫什么名字都可以,因为只会存在一个export default

exoprt和export default混合使用

exoprt和export default在同一个模块中同时使用,是支持的,虽然我们一般不会这么做

看一个栗子

output.js

const a = 'valueA1'

const b = 'valueB1'

const c = 'valueC1'

const d = 'valueD1'

function foo() {

  console.log(`foo执行,c的值是${c}`);

}

export {a}

export {b}

export default { b,d,foo}

input.js

import obj, {a,b } from './output'

console.log(a); //=>valueA1

console.log(b); //=>valueB1

console.log(obj); //=>{ b: 'valueB1', d: 'valueD1', foo: [Function: foo] }

as 重命名

通过 exoprt和export default导出的在import引入时都支持通过as进行重命名

看个栗子

还是上面的那个output.js

const a = 'valueA1'

const b = 'valueB1'

const c = 'valueC1'

const d = 'valueD1'

function foo() {

  console.log(`foo执行,c的值是${c}`);

}

export {a}

export {b}

export default { b,d,foo}

input.js

import {a as A} from './output'

import {* as A} from './output'//这是不支持的

import * as obj from './output'

console.log(A); //=>valueA1

console.log(obj); //=>{ a: 'valueA1',default: { b: 'valueB1', d: 'valueD1', foo: [Function: foo] },b: 'valueB1' }

as后面的变量是你要在input.js中使用的

重点看这一部分

import {* as A} from './output'//这是不支持的

import * as obj from './output'

console.log(obj); //=>{ a: 'valueA1',default: { b: 'valueB1', d: 'valueD1', foo: [Function: foo] },b: 'valueB1' }

* 代表了所有,包括了export和export default导出的

我们之前说import{}和export{},是一一对应关系,所以在export导出的,在import{}不支持使用*

关于 import,export,export default先介绍到这里,我们继续

require,exports,module.exports(记得后面的s)

这是 AMD规范

require

require是运行时调用,所以require理论上可以运用在代码的任何地方

require支持动态引入

例如,这样是支持的

let flag = true

if (flag) {

  const a = require('./output.js')

  console.log(a); //支持

}

require路径支持变量

let flag = true

let url = './output.js'

if (flag) {

  const a = require(url)

  console.log(a); //支持

}

通过require引入,是一个赋值的过程

exports 与 module.exports

根据AMD规范

每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

const exports = module.exports;

所以说

以下两种写法等价

exports.a ='valueA1'

module.exports.a='valueA1'

前面说在每个模块提供一个exports变量,指向module.exports。

所以不能直接给exports赋值,赋值会覆盖

const exports = module.exports;

直接给exports赋值会切断exports和 module.exports的关联关系

看一个栗子

output.js

const a = 'valueA1'

const b = 'valueB1'

const c = 'valueC1'

module.exports = { c}

exports.b = b//当直接给 module.exports时,exports会失效

module.exports.a = a

input.js

  const obj = require('./output.js')

  console.log(obj); //=>{ c: 'valueC1', a: 'valueA1' }

继续看代码 output.js

//部分省略

exports.b = b//这样可以生效

module.exports.a = a

input.js

  const obj = require('./output.js')

  console.log(obj); //=>{ b: 'valueB1', a: 'valueA1' }

再看一段代码 output.js

//部分省略

module.exports = { c}

module.exports.a = a

input.js

  const obj = require('./output.js')

  console.log(obj); //=>{ c: 'valueC1', a: 'valueA1' }

当直接给 module.exports时,exports会失效

交叉使用

在ES6中export default 导出的是一个对象

在AMD中exports和module.exports导出的也都是一个对象

所以如果你手中的项目代码支持两种规范,那么事可以交叉使用的(当然不建议这么去做)

通过export导出的不一定是一个对象

demo1

output.js

//部分省略

module.exports = { c}

module.exports.a = a

inputj.s

import obj from './output'

import {a} from './output'

console.log(a);//=>valueA1

console.log(obj);//=>{ c: 'valueC1', a: 'valueA1' }

demo2

output.js

const a = 'valueA1'

const b = 'valueB1'

const c = 'valueC1'

function foo() {

  console.log(`foo执行,c的值是${c}`);

}

export {a}

export default {b,c,foo}

export {b}

input.js

  const a = require('./output.js')

  console.log(a); //=>{ a: 'valueA1',default: { b: 'valueB1', c: 'valueC1', foo: [Function: foo] }, b: 'valueB1' }

总结

require,exports,module.exports属于AMD规范,import,export,export default属于ES6规范require支持动态导入,动态匹配路径,import对这两者都不支持require是运行时调用,import是编译时调用require是赋值过程,import是解构过程对于export和export default 不同的使用方式,import就要采取不同的引用方式,主要区别在于是否存在{},export导出的,import导入需要{},导入和导出一一对应,export default默认导出的,import导入不需要{}exports是module.exports一种简写形式,不能直接给exports赋值当直接给module.exports赋值时,exports会失效

438aab90317c72f9992a8d50540e4ab0.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dotnet core 应用是如何跑起来的 通过AppHost理解运行过程

在 dotnet 的输出路径里面,可以看到有一个有趣的可执行文件,这个可执行文件是如何在框架发布和独立发布的时候,找到 dotnet 程序的运行时的,这个可执行文件里面包含了哪些内容在回答上面的问题之前,请大家尝试打开 C:\…

算法题目——整数划分(HRBUST-2004)

题目链接:HRBUST-2004 递归法: 1.当n1时,此时只有1种解{1}; 2.当m1时,此时也只有1种解{1,1,1, … 3.当n> m时,要分为最大数包含m和不包含m两种情况。 ●包含m:此时就是{mx1,2…}. 其中x1x23.… n-m, 就相当于求和为n-m,最…

dotnet core 应用是如何跑起来的 通过自己写一个 dotnet host 理解运行过程

在上一篇博客是使用官方提供的 AppHost 跑起来整个 dotnet 程序。本文告诉大家在 dotnet 程序运行到托管代码之前,所需要的 Native 部分的逻辑。包括如何寻找 dotnet 运行时,如何加载运行时和框架然后跑起来业务端的 dll 文件的逻辑在上一篇博客告诉大家…

算法题目——多米诺骨牌问题(POJ-2663)

题目链接:POJ-2663 设有形状一样的多米诺牌,每张牌恰好覆盖棋盘上相邻的两个方格,即一张多米诺牌是一张 1 行 2 列或者 2 行 1 列的牌。那么,是否能够把 32 张多米诺牌摆放到棋盘上,使得任何两张多米诺牌均不重叠&…

算法题目——求众数

在c中有两个关联容器&#xff0c; 第一种是map&#xff0c;内部是按照key排序的&#xff0c;从小到大 第二种是unordered_map&#xff0c;容器内部是无序的&#xff0c;使用hash组织内容的。 #include<iostream> #include<map> #include<algorithm> using n…

2020武汉dotNET俱乐部分享交流会圆满结束

经过长达2个多月的准备&#xff0c;终于在12月5日圆满的举行了武汉首次dotNET俱乐部线下分享交流活动。我们一共精心准备了3个目前比较热门的主题&#xff0c;分别如下&#xff1a;Jason分享的《ABP开发框架的扩展应用》Leo分享的《基于Kubernetes的DevOps平台应用》Eleven分享…

算法——常用的数据结构/模板/基础知识

常用的数据结构/模板/基础知识(一)c——优先队列(priority_queue)最大堆和最小堆的写法(二)c中的全排列函数next_permutation()(三)迭代器的使用(四)数学知识数列求和(五)求最大公约数和最小公倍数(六)将数值型数据转化为string 类型(一)c——优先队列(priority_queue) 最大堆…

对 精致码农大佬 说的 Task.Run 会存在 内存泄漏 的思考

一&#xff1a;背景 1. 讲故事这段时间项目延期&#xff0c;加班比较厉害&#xff0c;博客就稍微停了停&#xff0c;不过还是得持续的技术输出呀&#xff01;园子里最近挺热闹的&#xff0c;精致码农大佬分享了三篇文章&#xff1a;为什么要小心使用 Task.Run [https://www.c…

算法题目——爬楼梯(动态规划)

题目链接:70.爬楼梯 类似题目:1646.获取生成数组中最大值 本题大家如果没有接触过的话,会感觉比较难,多举几个例子,就可以发现其规律。 爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。 那么第一层楼梯再跨两步就到第三层 ,第二层楼梯再跨一步就到第三层。 所以到…

Kubernetes 1.20 发布:妙啊

喜欢就关注我们吧&#xff01;Kubernetes 1.20 发布&#xff0c;这是 2020 年的第三版也是最终版。Kubernetes 1.20 还是最近这段时间以来&#xff0c;功能最密集的版本之一&#xff0c;此版本包含了 42 个增强功能&#xff0c;其中 11 个增强功能已逐步升级为稳定版&#xff0…

算法题目——生成括号匹配

题目链接:剑指offer.85 生成 n 对括号共需要 2n 步,每一步都面临两个选项,即生成左括号或者右括号,题目要求返回所有的情况,所以本问题很适合采用回溯法。 在生成左右括号时存在两个限制条件,一个是左括号或者右括号的数量都不能超过 n 个,第二个是已经生成的右括号数…

C# WPF开源控件库:MahApps.Metro

❝其实站长很久之前就知道这个开源WPF控件库了&#xff0c;只是一直欣赏不了这种风格&#xff0c;但也star了该项目。每次浏览该仓库时&#xff0c;发现star越来越多&#xff0c;也看到很多网友对它的褒奖&#xff0c;所以今天就向大家推荐这款WPF控件库。1. 具体有多优秀&…

golang 切片 接口_Golang语言常用关键字之 make 和 new

上一章中对于golang的语言基础说明如下&#xff1a;1 函数调用2 接口3 反射接下来我们来对golang的常用关键字进行说明&#xff0c;主要内容有&#xff1a;1. for 和 range2. select3. defer4. panic 和 recover5. make 和 new— — — — — — — — — — — — — — — —…

读书 | 数字化转型的道与术(上)

【数字化转型】| 作者 / Edison Zhou这是EdisonTalk的第312篇学习总结 最近在阅读钟华老师的新作《数字化转型的道与术》&#xff0c;记录和总结了一些学习笔记和感想&#xff0c;整理成文分享与你&#xff0c;本文为上半部分&#xff0c;希望能对也在参与数字化转型的各位童鞋…

算法题目——最长连续序列

题目链接:leetcode.128 思路: 1.现将数据存放到数组中去 2.再将数据存到一个集合set中去(方便去重,查找某一个元素是否存在于数组中) 3.循环该数组,若该元素的前一个元素不在数组中(通过集合来查找),说明它将会是一个连续序列的开始元素,在对该元素循环查看它的下一个元素…

如何在 ASP.NET Core 中实现全局异常拦截

异常是一种运行时错误&#xff0c;当异常没有得到适当的处理&#xff0c;很可能会导致你的程序意外终止&#xff0c;这篇就来讨论一下如何在 ASP.Net Core MVC 中实现全局异常处理&#xff0c;我会用一些 样例代码 和 截图 来说明这些概念。全局异常处理 其实在 ASP.Net Core M…

算法题目——被围绕的区域(dfs,bfs)

leetcode.130被围绕的区域 dfs解法: 深度优先遍历: 思路: 读取数据后 1.先将数据的四周进行bfs算法(因为只有与外围接触的点,才能不被包围) 算法执行中时,递归看看该点的上下左右有没有是O的,如果是O则标记为A 2.循环完四周之后,将数据中的O全部换成X,将全部的A换成O即得…

[Windows] 在 Microsoft Docs 网站中挖掘 MVVM 的各种学习资源

最近写了一些 MVVM 框架的文章&#xff0c;翻了一些 Microsoft Docs 的文档&#xff0c;顺便就对 MVVM 本身来了兴致&#xff0c;想看看更多当年相关的文档。在 MVVM 出现后十多年&#xff0c;我在不同的场合见到过多种 MVVM 的实现方式&#xff0c;也看到过各种 MVVM 框架的多…

算法题目——岛屿数量(bfs dfs)

题目链接:leetcode.200岛屿数量 dfs 重点:路过过的点做新标记 ,以防止重复路过 思路: 数据读取完成后 1.对所有数据进行一次循环 2.在循环内部,如果元素为‘1’则进入dfs算法 3.在深度优先遍历中,先将该元素标记为‘0’,在查看它的上下左右元素是否为‘1’,是‘1’则进…

注意| .NET开发者大会防疫须知 !

2020年12月19-20日中国.NET开发者大会将于苏州举办疫情常态化的情况下为确保大会顺利进行大会组委会从会议内容、会务筹备等方面均进行了全面的精细准备以下是组委会发布的参会防疫指南敬请所有现场参会的小伙伴认真阅读并严格按照防疫需求作相应准备▽为保证大会的顺利召开&am…