模块

模块就是实现特定功能的一组方法。

理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。但是,JavaScript 不是一种模块化编程语言,在 ES6 以前,它是不支持类,所以也就没有模块了。
JavaScript 社区做了很多努力,在现有的运行环境中,实现”模块”的效果。

原始写法
只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。

function f1(){//...
}
function f2(){//...  
}

上面的函数 f1() 和 f2(),组成一个模块。使用的时候,直接调用就行了。
缺点:污染全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。

对象写法
为了解决上面的缺点,可以把模块写成一个对象,所有的模块成员都放到这个对象里面。

var module1 = new Object({num: 0,f1: function (){//...},f2: function (){//...}
});

上面的函数 f1() 和 f2(),都封装在 module1 对象里。使用的时候,调用这个对象的属性
module1.f1()

这样的写法会暴露所有模块成员,内部状态可以被外部改写。比如,外部代码可以直接改变内部计数器的值。
module1.num = 1

立即执行函数写法
使用立即执行函数,可以达到不暴露私有成员的目的

var module2 = (function() {var num = 0;
var f1 = function() {alert(num)
}
var f2 = function() {alert(num + 1)
}
return {f1: f1,f2: f2
}
})()

使用上面的写法,外部代码无法读取内部的 num 变量。
console.log(module2.num) //undefined

主流模块规范

CommonJS
CMD
AMD

现阶段的标准

ES6 标准发布后,module 成为标准,标准使用是以 export 指令导出接口,以 import 引入模块,但是在 node 模块中,我们依然采用的是 CommonJS 规范,使用 require 引入模块,使用 module.exports 导出接口。

export 导出模块

export 语法声明用于导出函数、对象、指定文件(或模块)的原始值。
export 有两种模块导出方式:命名式导出(名称导出)和默认导出(定义式导出),命名式导出每个模块可以多个,而默认导出每个模块仅一个。

export { name1, name2};
export { a1 as name1, a2 as name2 };
export let name1, name2;
export let name1 = a1, name2 = a1;export default expression;
export default function (a) { console.log(a) }
export default function f1(a) { console.log(a) }
export { name1 as default};export * from name1;
export { name1, name2} from a1;
export { a1 as name1, a2 as name2 } from b;
  • name1 ,name2 ,导出的标识符。导出后,可以通过这个标识符在另一个模块中使用 import 引用
  • default 设置模块的默认导出。设置后import不通过标识符而直接引用默认导出
  • “*” 继承模块并导出继承模块所有的方法和属性
  • as 重命名导出“标识符”
  • from 从已经存在的模块、脚本文件导出

命名式导出
模块可以通过 export 前缀关键词声明导出对象,导出对象可以是多个。这些导出对象用名称进行区分,称之为命名式导出。

export { fn }; // 导出一个已定义的函数
export const foo = Math.sqrt(2); // 导出一个常量

我们可以使用 * 和 from 关键字来实现的模块的继承

export * from 'article';

模块导出时,可以指定模块的导出成员。导出成员可以认为是类中的公有对象,而非导出成员可以认为是类中的私有对象:

var name = '石昊';
var age = 6;export {name, age};
// 相当于导出 {name:name, age:age}

模块导出时,我们可以使用 as 关键字对导出成员进行重命名:

var name = '石昊';
var age = 6;export {name as nickName, age};

注意,下面的语法有严重错误的情况:

// 错误演示1
export 1; // 错误演示12
var a = 100;
export a;

export在导出接口的时候,必须与模块内部的变量具有一一对应的关系。直接导出1没有任何意义,也不可能在 import 的时候有一个变量与之对应.
export a 虽然看上去成立,但是 a 的值是一个数字,根本无法完成解构,因此必须写成 export {a} 的形式。即使a被赋值为一个 function,也是不允许的。而且,大部分风格都建议,模块中最好在末尾用一个export导出所有的接口,例如:

export {f1 as default,a,b,c};

默认导出
默认导出也被称做定义式导出。命名式导出可以导出多个值,但在在 import 引用时,也要使用相同的名称来引用相应的值。而默认导出每个导出只有一个单一值,这个输出可以是一个函数、类或其它类型的值,这样在模块 import 导入时也会很容易引用。

export default function() {}; // 可以导出一个函数
export default class(){}; // 也可以出一个类

命名式导出与默认导出
默认导出可以理解为另一种形式的命名式导出,默认导出可以认为是使用了 default 名称的命名式导出。

下面两种导出方式是等价的:

const name = '石昊';
export default name;
export { name as default };

export 使用示例

使用名称导出一个模块时:

// "info.js" 模块
export function getName(name) {if(name === '唐三'){return '海神'}else if(name == '千仞雪'){return '天使神'}else if(name == '比比东'){return '罗刹神'}else{return '酱油'}
}
const weapon = '海神三叉戟';
export { weapon };

在另一个模块(脚本文件)中,我们可以像下面这样引用:

import { getName, weapon } from 'info';
console.log(getGodName("比比东")); // 罗刹神
console.log(weapon); // 海神三叉戟

使用默认导出一个模块时:

// "info.js"模块
export default function(name) {if(name === '唐三'){return '海神'}else if(name == '千仞雪'){return '天使神'}else if(name == '比比东'){return '罗刹神'}else{return '酱油'}
}

在另一个模块(脚本文件)中,我们可以像下面这样引用,相对名称导出来说使用更为简单:

// 引用 "info.js"模块
import getName from 'info';
console.log(getName("唐三")); // 海神

import 导入模块

import 语法用于从已导出的模块、脚本中导入函数、对象、指定文件(或模块)的原始值。

import 模块导入与 export 模块导出功能相对应,也存在两种模块导入方式:命名式导入(名称导入)和默认导入(定义式导入)。

import 的语法跟 require 不同,而且 import 必须放在文件的最开始,且前面不允许有其他逻辑代码,这和其他所有编程语言风格一致。

import defaultMember from "module-name";
import * as name from "module-name";
import { member1 } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member1 [ , [...] ] } from "module-name";
import defaultMember, * as name from "module-name";
import "module-name";
  • defaultMember 导入默认导出成员
  • name 从将要导入模块中收到的导出值的名称
  • member1,member1 导入指定名称的多个成员
  • alias 别名,对指定导入成员进行的重命名
  • module-name 要导入的模块,是一个文件名
  • as 重命名导入成员名称
  • from 从已经存在的模块、脚本文件等导入

命名式导入
我们可以通过指定名称,就是将这些成员插入到当作用域中。导入时,可以导入单个成员或多个成员:

// 花括号里面的变量与 export 后面的变量一一对应
import { member } from "my-module";
import { name, age } from "my-module";

通过 * 符号,我们可以导入模块中的全部属性和方法。当导入模块全部导出内容时,就是将导出模块所有的导出绑定内容,插入到当前模块的作用域中:

import * as myModule from "my-module";
// myModule 可以访问到"my-module"所有的导出绑定内容

导入模块对象时,也可以使用as对导入成员重命名,以方便在当前模块内使用:

import {reallyReallyLongModuleMemberName as shortName} from "my-module";

导入多个成员时,同样可以使用别名:

import {reallyReallyLongModuleMemberName1 as shortName1, reallyReallyLongModuleMemberName2 as shortName2} from "my-module";

导入一个模块,但不进行任何绑定:

import "my-module";

默认导入
在模块导出时,可能会存在默认导出。同样的,在导入时可以使用import指令导出这些默认值。

直接导入默认值:

import myDefault from "my-module";

也可以在命名式导入中,同时使用默认导入:

import myDefault, * as myModule from "my-module"; // myModule 做为命名空间使用
import myDefault, {foo, bar} from "my-module"; // 指定成员导入

import 使用示例

// 导出文件 a.js
function getData(url, callback) {let xhr = new XMLHttpRequest();xhr.onload = function () {callback(this.responseText)};xhr.open("GET", url, true);xhr.send();
}export function getUserInfo(url, callback) {getData(url, data => callback(JSON.parse(data)));
}// 导入文件 b.js
import { getUserInfo } from "b";
getUserInfo("http://baidu.com", data => {console.log(data);
}

default 关键字

// a.js
export default function() {}// 等效于
function a() {};
export {a as default};

在import的时候,可以这样用:

import a from './a';// 等效于
import {default as a} from './d';

这个语法糖的好处就是import的时候,可以省去花括号{},简单的说,如果import的时候,你发现某个变量没有花括号括起来(没有*号),那么你在脑海中应该把它还原成有花括号的as语法。

import $,{ each, map } from 'jquery';
// import 后面第一个 $ 是 {defalut as $} 的替代写法

as 关键字
as简单的说就是取一个别名 export 和 import 中都可以使用:

// a.js
var a = function() {};
export {a as fun};// b.js
import {fun as a} from './a';
a();

上面这段代码,export 的时候,对外提供的接口是 fun,它是a.js 内部 a 这个函数的别名。
import 中的 as 就很简单,就是你在使用模块里面的方法的时候,给这个方法取一个别名,好在当前的文件里面使用。之所以是这样,是因为有的时候不同的两个模块可能通过相同的接口,比如有一个c.js也通过了fun这个接口:

// c.js
export function fun() {};

如果在 b.js 中同时使用 a 和 c 这两个模块,就必须想办法解决接口重名的问题,as 就解决了。

JS 中的 import 与 export相关推荐

  1. vue滚动条禁止_vue.js中实现禁止浏览器滚动方法

    大家好,本次在开发项目中,点击按钮,弹出一个自定义的弹出窗口和遮罩层,因为页面的超出一屏,有滚动条,但是想让弹出窗时候,禁止浏览器滚动,那么就简单写一个方法给大家. 思路是这样的,当弹窗弹出时候,让b ...

  2. import export php,import与export在node.js中的使用方法

    import与export是es6中模块化的导入与导出,node.js现阶段不支持,需要通过babel进行编译,使其变成node.js的模块化代码.(关于node.js模块,可参考其他node.js模 ...

  3. 使用es6中import和export报错

    在学习import和export时,写了一个小demo进行测试 //index.html<script> import test from './test.js' test() </ ...

  4. 彻底搞清楚javascript中的require、import和export

    为什么有模块概念 理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. 但是,Javascript不是一种模块化编程语言,在es6以前,它是不支持"类"( ...

  5. js中export的问题

    在JS中 定义一个函数名字是export 会报错(ff不报错,ie会),修改成其他名字就行了. 原因是,export是ECMA为将来保留的词(Words reserved for ECMA exten ...

  6. import和export在浏览器中的使用方式

    import和export在浏览器中的使用方式 一般情况下,import 和 export 的使用通常是在 webpack.Vite 等构建工具中已模块的形式使用,而想在浏览器中直接使用,则需要通过一 ...

  7. JS的export , export default,import,export(导出js)和import(引入js)完整用法

    A.规范文件名 我们确定我们有一个文件是common.js 这个文件在根目录的static文件夹下 路径如下 |-根目录/static/common.js export(导出)和import(引入) ...

  8. JS中export怎么用

    一.export 用法 有两种不同的导出方式:命名导出和默认导出.命名导出可以导出多个接口,而默认导出,只能导出一个. 1.命名导出: 导入时,必须使用导出接口的名字. // 导出事先定义的特性 ex ...

  9. js模块化:require、import和export

    前言 编写js模块必须要搞懂import和export的关系 Google Chrome 84.0.4147.135 (正式版本) (64 位) (cohort: Stable Installs On ...

最新文章

  1. 关于Android studio run 按钮灰色无法运行的总结
  2. HIVE 一行转多行输出办法
  3. 淘汰率最高的腾讯产品面试题
  4. Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种...
  5. Git拉取指定远程分支
  6. 推荐阅读20100708
  7. 欢迎清风艾艾在ITPUB博客安家!
  8. 游戏技能一:激光扫射的实现【CocosCreator 2D】【TypeScript】
  9. oppo开启系统更新服务器,oppo手机系统升级开不了机怎么办
  10. 让你久等了《开源安全运维平台OSSIM疑难解析--入门篇》正式出版
  11. Oracle数据库update语句用法,多表批量更新对应的字段值
  12. 深度学习的不确定性(Uncertainty/confidence score)与校准(Calibration)
  13. Java程序设计(2021春)——第三章类的重用笔记与思考
  14. 下载yahoo股票历史数据
  15. 计算机实验楼应用需求分析,校园网络信息化需求分析报告
  16. echarts+bmap地图去掉底图可点功能
  17. 这竟然不是阿汤哥?这个「真的吓人」视频火爆全网
  18. ExoPlayer的缓存 三 SimpleCache的使用
  19. go reflect Elem() 深入学习
  20. oracle vault 权限,详说Oracle Vault——原理、安装与配置

热门文章

  1. 7-1 有课几何 (10 分)
  2. 【阵列信号处理】矩阵代数基础知识总结
  3. AD域(active directory)基础概念(一)
  4. 量化交易:止盈策略与回测
  5. 2021年中国通信基建现状及重点企业:我国5G基站累计建成开通142.5万个,5G投资额达1849亿元[图]
  6. 数字政府的建设现状与主要问题
  7. 信而泰推出100G五速卡补通信测试短板
  8. 什么是单例模式和工厂模式
  9. 获取webbrowser的html,WebBrowser 获取网页内容
  10. LINUX_常用命令讲解