资讯专栏INFORMATION COLUMN

javascript基础之模块

keithyau / 2003人阅读

摘要:两者对比就像下面这样通过对象把函数向外开放而使用的模块就像下面通过导出方法当然了,的模块肯定是比匿名函数自执行更加高级的一种封装了。相比于匿名函数,模块具有下面几种特点。

什么是ES6模块?

在ES6中,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。在看到这里的时候感觉很熟悉,这不就是匿名函数自执行,然后一个个匿名函数放在一个个文件中的么,一个模块就是一个放在文件中的匿名自执行函数。两者对比就像下面这样:

// add.js 
(function(window){
    function add(a, b) {
       return a + b;
    }
    
    window.add = add // 通过window对象把 add 函数向外开放
})(window)

而使用ES6的模块, 就像下面

// add.js
function add(a, b) {
  return a + b;
}
export default add; // 通过export 导出 add方法

当然了,ES6的模块肯定是比匿名函数自执行更加高级的一种封装了。相比于匿名函数,ES6模块具有下面几种特点。

1. ES6默认使用严格模式, 而不需要使用 "use strict"
2. ES6模块是编译时加载,对代码进行静态分析
3. 对外抛出接口的时候,不会污染全局的对象
4. 能够有效的处理依赖, 而且只会在第一次加载模块时,代码运行一次。后面再次加载,不会重复 运行,会从缓存中读取
......暂时这些,以后待补充

至于为什么时候ES6的模块产生的历史就不讨论,网络上很多。个人感觉明白了它的历史就能更好的明白它的特性。

export 与 import

说到模块,就需要想到两点,一个是模块的对外接口,后面文章中使用导出来表示,另外一个是引入其他模块的接口,后面文章中使用导入来表示。

export命令用于规定模块的导出import命令用于模块的导入
重头戏就来了,怎么更好更快的理解模块的导出导入

当模块引入其他模块的时候,最终是获取其模块导出的值(基本数据类型或者引用类型)。于是可以这样去理解,当我们引入的模块(文件)已经确定下来了,那么导入的值也就确定下来。

// add.js
function add(a, b) {
   return a + b;
}
export default add

// main.js
import add from "./add.js"
add(1,2) // 3 

上面导入的是 add.js 这个模块,其实主要是把add.js 中的 add 函数进行引入。

当需要到导入多个值的时候,可以通过对象来返回多个所需要的值。

// util.js
function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}
// 通过对象来返回多个值
export default {add: add, reduce: reduce};

// main.js
import util from "./util.js"
console.log(util) // {add: add, reduce: reduce}

到这里,我个人觉得模块的导入导出基本上就已经很好了。因为这样不管是导出还是导入,对接的接口都是简单方便。

当然这只是我觉得。还是上面的例子

// util.js
function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}

export default {add: add, reduce: reduce, name: "util"}

// main.js
import util from "./util.js"

util.add(1, 2) // => 3

util.reduce(4, 3) // => 1

util.name // => "util"

有人说,当导入的是值是对象的时候,需要多次去使用对象获取属性。 就像上面需要多次使用util去获取属性。ES6中不是有解构赋值么,用来处理对象多次获取属性的问题,那么导入对象的时候,也可以这样去处理。

于是按照对象的解构赋值,对上面的 main.js 改变。

// main.js
import {add: addFn} from "./util.js"
// 这里在`webpack`中编译就已经报错了, ES6模块不支持这种方式

// 使用另外一种解构方式,`导出`模块的属性名与`导入`的变量名一致

// main.js
import { add } from "./util.js"
console.log(add)  // undefined
// 这里在`webpack`编译中没有报出错误,但是还有警告: "export "add" was not found  

// 于是对 util.js 的`导出`进行改变
//util.js
 function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}

export {add, reduce, name: "util"}
// 当修改完util.js 就完成了util.js模块`导出` 与 main.js模块的`导入`对接

模块的导入导出大致可以分为两种模式

1. default 模式

default 模式下,模块中导出的值可以使用任何类型(不管是基本类型还是引用类型),都可以对外输出。而导入的此模块也是很简单,提供一个接收的变量就可以(推荐这种模式)
例子如下:

// util.js 
function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

const obj = { add, reduce };

export default obj;
// main.js
import util from "./util.js";
// util 是可以变换任意名称
console.log(util)// => {add: ƒ, reduce: ƒ}
2. { xxx } 模式

{ xxx } 是不需要在模块导出的时候使用default的。但是这种方式下,导出的值一定是object的。
导入的模块时是需要使用 { xxx }来接收。而且接收的变量名称还必须与导出模块属性名的一样。
例子如下:

// util.js 
function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

let obj = { add, reduce };
// export obj; //webpack 编译报错

export { add, reduce }; 

// 除了这样直接导出对象,还可以像下面这样

export let name = "util";
// 与 export { name } 效果一样;

深入了解的话,两者还是可以一起合用

function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

export let name = "util";
export { add, reduce };
// 相当于把这些属性合并在一起
// main.js
import { add, reduce, name } from "./util.js" 
console.log(add) // add(a, b) { return a + b; }
console.log(name) // util 
as 重命名

as 重命名主要是用于 { xxx }模式。因为在导出的时候,属性名是被确定下来,而在导入此模块的时候,变量名需要跟此属性名一样才能获取对应的值。而使用 as 不仅能够帮助导出模块把属性名重命名,也能够帮导入模块把接收的变量名进行重命名。
例子如下:

// util.js
function add(a, b) {
    return a + b;
}

export { add as addFn};
// main.js
import { addFn as add } from "./util.js"

console.log(add) // add(a, b) { return a + b; }

上面是个人关于ES6的模块个人理解和学习心得。

另外想要深入了解的可以查看官方文档 http://www.ecma-international...

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

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

相关文章

  • node学习系列基础(二)

    摘要:由于这种特性,某一个任务的后续操作,往往采用回调函数的形式进行定义。另外,回调函数本身的第一个参数,约定为上一步传入的错误对象。这种写法有一个很大的好处,就是说只要判断回调函数的第一个参数,就知道有没有出错,如果不是,就肯定出错了。 REPL环境 在命令行键入node命令,后面没有文件名,就进入一个Node.js的REPL环境(Read–eval–print loop,读取-求值-输出...

    zhaot 评论0 收藏0
  • javascript知识点

    摘要:模块化是随着前端技术的发展,前端代码爆炸式增长后,工程化所采取的必然措施。目前模块化的思想分为和。特别指出,事件不等同于异步,回调也不等同于异步。将会讨论安全的类型检测惰性载入函数冻结对象定时器等话题。 Vue.js 前后端同构方案之准备篇——代码优化 目前 Vue.js 的火爆不亚于当初的 React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。我们先在代...

    Karrdy 评论0 收藏0
  • 前端每周清单半年盘点 Node.js 篇

    摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。对该漏洞的综合评级为高危。目前,相关利用方式已经在互联网上公开,近期出现攻击尝试爆发的可能。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢...

    kid143 评论0 收藏0
  • 前端每周清单第 44 期: 2017 JS 调查报告、REST 接口实时化、ESM 的过去与未来

    摘要:巅峰人生年老兵思路上的转变,远比单纯提升技术更有价值本文节选自赵成教授在极客时间开设的赵成的运维体系管理课,是其对自己十年技术生涯的回顾与总结。赵成教授来自美丽联合集团,集团旗下两大主力产品是蘑菇街和美丽说,目前负责管理集团的技术服务团队。 showImg(https://segmentfault.com/img/remote/1460000012476504?w=1240&h=826...

    MASAILA 评论0 收藏0
  • Javascript模块化编程模块的写法】

    摘要:模块化编程,已经成为一个迫切的需求。但是,不是一种模块化编程语言,它不支持类,更遑论模块了。本文总结了当前模块化编程的最佳实践,说明如何投入实用。就是模块的基本写法。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。 随着WEB的快速崛起,网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑。 Ja...

    Riddler 评论0 收藏0

发表评论

0条评论

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