文档章节

明白 JS 模块化

王福林
 王福林
发布于 2017/09/08 16:51
字数 917
阅读 12
收藏 0

明白 JS 模块化

模块化是什么,有什么用?

模块化就是将一个大的功能拆分为多个块,每一个块都是独立的,你不需要去担心污染全局变量,命名冲突什么的。

那么模块化的好处也就显然易见了

  • 解决命名冲突
  • 依赖管理
  • 代码更加可读
  • 提高复用性

早期苦逼的前端er

但是,JS 这门语言在最初是没有这个设计的。所以也就苦了早期的前端开发者。下面介绍下最开始的写法。

函数封装

这个嘛,谁都会,最大的缺点就是污染全局作用域了

function fn1() {
    // balabalabala
}
function fn2() {
    // balabalabala
}

对象

这个嘛,也是谁都会的,最大的缺点就是没有私有变量,外部能改

var myModule = {
    var1: 1,
    fn1: function() {}
}

立即执行函数

这个嘛,高级了点,并且也有了模块化的意思,这种写法在老项目中很常见,一个 JS 文件中就是一个立即执行函数

(function(){
   // ....
})()

CommonJS

浏览器这边表示没有模块化还行,就是写逻辑麻烦了点。但是搞服务端的必须得有这玩意啊,所以 Node.js 第一个搞出了 CommonJS规范

// a.js
module.exports = {
    a: 1
}
// or 
exports.a = 1

// b.js
var module = require('./a.js')
module.a // -> log 1

上面的写法很好用,但是 module.exports 和 exports 是咋回事?为啥这几句代码就实现模块化了,让我们来看一下基础的实现

先说 require 吧

var module = require('./a.js')
module.a 
// 这里其实就是包装了一层立即执行函数,这样就不会污染全局变量了,
// 重要的是 module 这里,module 是 Node 独有的一个变量
module.exports = {
    a: 1
}
// 基本实现
var module = {
  id: 'xxxx', // 我总得知道怎么去找到他吧
  exports: {} // exports 就是个空对象
}
// 这个是为什么 exports 和 module.exports 用法相似的原因
var exports = module.exports 
var load = function (module) {
    // 导出的东西
    var a = 1
    module.exports = a
    return module.exports
};
// 然后当我 require 的时候去找到独特的
// id,然后将要使用的东西用立即执行函数包装下,over

再来说说 module.exports 和 exports,用法其实基本是相似的,但是不能对 exports直接赋值,不会有任何效果,看了上面代码的同学肯定明白为什么了。

CommonJS规范是 Node 独有的,浏览器中使用就需要用到 Browserify 解析了,所以后面又蹦出了两个规范。

AMD && CMD

AMD 是由 RequireJS 提出的,CMD 由 SeaJS 提出。两者用法基本相似,当然现在用的人应该也不多了,了解下语法,看项目的时候不至于懵逼就行

// AMD
define(['./a', './b'], function(a, b) { 
    a.do()
    b.do()
}) 
define(function(require, exports, module) {   
var a = require('./a')  
a.doSomething()   
var b = require('./b') 
b.doSomething() 
})

原生登场

ES6总算原生支持模块化了,毁誉参半吧。当然这个语法还是早支持早好。

// 引入的语法就这样 import,XXX 这里有很多语法变化
import XXX from './a.js'
// 导出也有很多语法变化的写法,基本的就这两个,反正语法没什么难得
export function a() {}
export default function() {}

最后

这里基本的介绍了下模块的几种写法,如有错误,请提出,谢谢!

答疑

评论里有问到为什么直接对 exports 赋值无效。首先 require 出来的是 module.exports 对象,然后看下面的代码

var a = {}
a.exports = {}
// 把 e 看成 exports,现在 e === a.exports
var e = a.exports
// 引用的关系,同时也修改了 a.exports
e.c = 1
console.log(a.exports.c) // -> 1

// 但是当给 e 赋值的话就等于修改了引用了, 所以并没有修改 a.exports
e = xxxx

本文转载自:https://juejin.im/post/59a575b06fb9a0247c6eee02

共有 人打赏支持
上一篇: ESLint - 简介
下一篇: 深入理解 ES6
王福林
粉丝 10
博文 94
码字总数 37444
作品 0
徐汇
程序员
私信 提问
JavaScript 模块化解析

作者: zhijs from 迅雷前端 原文地址:JavaScript 模块化解析 随着 JavasScript 语言逐渐发展,JavaScript 应用从简单的表单验证,到复杂的网站交互,再到服务端,移动端,PC 客户端的语言支...

迅雷前端
10/22
0
0
RequireJS与SeaJS模块化加载示例

web应用越变的庞大,模块化越显得重要,尤其Nodejs的流行,Javascript不限用于浏览器,还用于后台或其他场景时,没有Class,没有Package的Javascript语言变得难以管理,于是出现CommonJS项目...

nosand
2014/05/04
0
10
从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十六 ║ Vue前篇:ES6初体验 & 模块化编程

缘起 昨天说到了《[从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║ Vue前篇:JS对象&字面量&this](https://www.cnblogs.com/laozhang-is-phi/p/9580807.html)》,通过总体来看,好像大家...

laozhang_is_phi
09/05
0
0
【99JS】之二:路径自动调整

 上一篇,99给大家介绍了使用js控制“:nth-child()”的方法,今天99继续给大家介绍一个使用js自动调整路径的相关介绍,希望大家喜欢。 目标: 路径自动调整 需求是这样的:在javascript 开发...

石佛慈悲
2014/01/03
0
0
JavaScript模块化进阶

写在前面 模块化简单来说就是是指把一个复杂的系统分解到多个模块以方便编码。JS模块化的大致流程为:CommonJS(服务端) -> AMD(浏览器端)-> UMD(兼容了CommonJS和AMD) -> ES Module(E...

Jee
12/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

新手也能看懂,消息队列其实很简单

该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址:https://github.com/Snailclimb/JavaGuide. 本文内容思维导图: 消息...

阿里云官方博客
43分钟前
5
0
如何在Chrome浏览器中启动deviceready事件(尝试调试phonegap项目)?

我正在开发PhoneGap应用程序,我希望能够在Chrome中调试它,而不是在电话上调试。但是,我在onGetReady()函数中初始化我的代码,该函数在PhoneGap触发“deviceready”事件时触发。由于Chr...

kisshua
今天
10
0
nginx中部署vue打包后的静态文件

如何在nginx中部署静态资源就不描述了, 请看我的这篇博客 将vue脚手架项目打包后的静态文件放到nginx上, 发现有个问题, 即url上有#, 怎么去掉这个#呢. 1 项目中router的mode 路由的mode要为h...

克虏伯
今天
13
0
JS容易理解错误的地方

在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了? 1 var hi = {};2 function sayHello(hi) { ...

器石_
今天
10
0
Java开发学习--MongoDB

之前只学过sql,第一次使用非关系型数据库。以前对于关系型数据库与非关系型数据库的概念很模糊,通过这次的学习对这两者有了一个清晰的概念。 主键 在MongoDB中,主键名叫"_id",如果在生成...

微笑向暖wx
今天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部