文档章节

明白 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

共有 人打赏支持
王福林
粉丝 9
博文 93
码字总数 36521
作品 0
徐汇
程序员
RequireJS与SeaJS模块化加载示例

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

nosand
2014/05/04
0
10
【99JS】之二:路径自动调整

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

石佛慈悲
2014/01/03
0
0
使用SeaJS实现模块化JavaScript开发

前言 SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。与jQuery等JavaScript框架不同,SeaJS不会扩展封装语言特性,而只是实现JavaScrip...

green001
2014/04/01
0
2
seaJs学习笔记之javascript的冲突问题

seaJs是一个处理模块化的JS开源库,在学习seaJs之前还是要了解一下什么是JS模块化的一些概念,知道这个之后,会更好的了解seaJs的使用。  首先先看一下下面的这个问题。当你的学习教程网站...

xuexijc
2013/11/27
0
0
使用SeaJS实现模块化JavaScript开发

前言 SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。与jQuery等JavaScript框架不同,SeaJS不会扩展封装语言特性,而只是实现JavaScrip...

i33
2013/03/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 我居然在 osc 里追剧

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @舆情风控小组 :分享王菲的单曲《笑忘书》 《笑忘书》- 王菲 手机党少年们想听歌,请使劲儿戳(这里) @艾尔库鲁斯:如果给大家一个选择的机...

小小编辑
48分钟前
70
8
rabbitMq的客户端使用笔记

1、channel声明队列的queueDeclare方法的参数解析 durable: 是否持久化, 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,如果想重启之后还存在就要使队列持久化,保存到Erlang自...

DemonsI
56分钟前
0
0
“全新” 编程语言 Julia开箱体验

本文共 851字,阅读大约需要 3分钟 ! 概 述 Julia 是一个 “全新”的高性能动态编程语言,前两天迎来了其 1.0 正式版的重大更新。Julia集 Python、C、R、Ruby 之所长,感觉就像一种脚本语言...

CodeSheep
今天
12
0
软件自动化测试初学者忠告

题外话 测试入门 很多受过高等教育的大学生经常问要不要去报测试培训班来入门测试。 答案是否。 高等教育的合格毕业生要具备自学能力,如果你不具备自学能力,要好好地反省一下,为什么自己受...

python测试开发人工智能安全
今天
5
0
java并发备忘

不安全的“先检查后执行”,代码形式如下: if(条件满足){ //这里容易出现线程安全问题//doSomething}else{//doOther} 读取-修改-写入 原子操作:使用CAS技术,即首先从V中读取...

Funcy1122
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部