[转]js模块化(一)
java有类文件、Python有import关键词、Ruby有require关键词、C#有using关键词、PHP有include和require、CSS有@import关键词,但是对ES5版本的javascript来说,javascript通过script标签引入代码的方式显得杂乱无章,语言自身毫无组织和约束能力,人们不得不用命令空间等方式人为地约束代码,以求达到安全和易用的目的。本文将详细介绍javascript中的模块组织
反模式
反模式(Anti-Pattern)指没有使用任何模块系统
简单地,把不同的函数(以及记录状态的变量)放在一起,就算是一个模块
function m1(){
//...
}
function m2(){
//...
}
上面的函数m1()和m2(),组成一个模块。使用的时候,直接调用就行了。
这种做法的缺点很明显:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系
字面量
为了解决上面的缺点,可以把模块写成一个字面量,所有的模块成员都放到这个对象里面
var module1 = new Object({
_count : 0,
m1 : function (){
//...
},
m2 : function (){
//...
}
});
上面的函数m1()和m2(),都封装在module1对象里。使用的时候,就是调用这个对象的属性
module1.m1();
但这种写法会暴露所有模块成员,内部状态可被外部改写。比如,外部代码可以直接改变内部计数器的值
module1._count = 5;
IIFE
使用"立即执行函数"(Immediately-Invoked Function Expression,IIFE)可以达到不暴露私有成员的目的
var module1 = (function(){
var _count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
使用上面的写法,外部代码无法读取内部的_count变量
console.info(module1._count); //undefined
IIFE传参
如果一个模块需要继承另一个模块,则需要IIFE传参
var module1 = ( function (mod){
mod.m3 = function () {
//...
};
return mod;
})(window.module1 || {});
命名空间
如果采用IIFE的方法,随着模块的增多,仍然污染了全局环境。
而命名空间(Namespace)可以通过只暴露类似于一个'namespace'的全局变量,来实现所有模块的声明,进而解决全局环境的污染问题
//math.js
namespace('math', [], function(){
function add(a, b) { return a + b; }
function sub(a, b) { return a - b; }
return {
add: add,
sub: sub
}
}) //calculator.js
namespace('calculator', ['math'], function(m){
var action = 'add';
function compute(a,b) {
return m[action](a, b);
}
return {
compute: compute
}
})
var namespace = (function(){
//缓存所有模块
var cache = {};
function createModule(name/*模块名*/,deps/*依赖列表*/,definition/*定义*/){
//如果只有模块名,则直接输出
if(arguments.length === 1){
return cache[name];
}
//取得所有模块的依赖
deps = deps.map(function(depName){
return namespace(depName);
})
//初始化模块并返回
cache[name] = definition.apply(null,deps); return cache[name];
}
return createModule;
})()
最后
虽然,使用命名空间可以解决全局环境污染的问题,但是却无法解决模块依赖管理的问题
如下图所示,module2依赖于module1和module3,则代码如下
<script src="module1.js"></script>
<script src="module3.js"></script>
<script src="module2.js"></script>
但,如果模块组织如下所示
甚至,如下所示
这时,手动地处理模块之间的依赖关系就不现实了,需要使用AMD、CMD、ES6 MODULE等来处理
[转]js模块化(一)的更多相关文章
- JS模块化开发:使用SeaJs高效构建页面
一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- ReactJS webpack实现JS模块化使用的坑
从一个原生HTML/CSS/JS模式的网页改造到ReactJS模块化的结构,需要以下步骤: (1)引用ReactJS框架 ->(2)使用webpack 工具 -> (3)配置webpack ...
- JS 模块化和打包方案收集
1.这里想讨论的是拆分规则,不是在问哪个工具怎么使用.2.这里没有在想找正确答案,因为感觉这个问题要结合具体业务场景. 随着项目开发越来越大,一开始代码全打包到一个文件的方式,让文件越来越大,接下来要 ...
- 闲聊——浅谈前端js模块化演变
function时代 前端这几年发展太快了,我学习的速度都跟不上演变的速度了(门派太多了,后台都是大牛公司支撑类似于facebook的react.google的angular,angular的1.0还 ...
- js模块化历程
这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生与变迁,展望ES6模块化标准的未来.经历过这段历史的人或许会感到沧桑,没经历过的人也应该知道这段历史. 无模块时代 在ajax还未提出 ...
- js 模块化的一些理解和es6模块化学习
模块化 1 IIFE 2 commonjs 3 浏览器中js的模块化 4 简单理解模块加载器的原理 5 es6 之前在参加百度前端技术学院做的小题目的时候,自己写模块的时候 都是写成立即调用表达式( ...
- 探索javascript----浅析js模块化
引言: 鸭子类型: 面向对象的编程思想里,有一个有趣的概念,叫鸭子类型:“一只鸟走起来像鸭子.游起泳来像鸭子.叫起来也像鸭子,那它就可以被当做鸭子.也就是说,它不关注对象的类型,而是关注对象具有的行为 ...
- js 模块化历程
作者:吕大豹 网址:http://www.cnblogs.com/lvdabao/p/js-modules-develop.html 这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生 ...
- Ampersand.js - 模块化的 JS 应用程序开发框架
Ampersand.js 是一个高度模块化,松耦合,用于构建先进的 JavaScript 应用程序的框架.通过良好定义的方法,结合了一系列微小的 CommonJS 模块.条理清晰,没有多余的冗余代码. ...
随机推荐
- 請問各位大大,我要將listview顯示的縮圖加入到listview2,請問該如何做呢
請問各位大大,我要將listview顯示的縮圖加入到listview2,請問該如何做呢?下面的function可以將listview的縮圖加到listview2但是全都顯示listview1第一張的圖 ...
- 愚人节老板发话了,免费送书 + 免费入驻Java知识星球!!
愚人节快乐,今天的活动很重磅! 1.免费送5本重量级技术书籍,不骗人,小程序随机抽奖送出哦! 2.免费进星球,哈哈不可能,愚人节快乐!不过今天有重大优惠,见下文! 活动一:免费送出5本重量级书籍 赠书 ...
- xcart小数点位数
xcart小数点的位数默认是2位,有时候需要根据需要更改位数:一开始以为把数据库中的数据类型的位数更改过后,就能生效,结果发现xcart在程序中作了限制,只能是2位.那么只能通过更改程序的方式来更改了 ...
- SG函数模板(洛谷2197nim游戏
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> ...
- 【JZOJ3237】间谍派遣
description 你是M,一个雇佣N个标号为从1到N的间谍的情报机关的总管.每个间谍被派往不同的国家并在那获取重要情报. 如下是你的任务: 1.在部分间谍间组织会面.每次会面在两个间谍间进行,两 ...
- 廖雪峰Java15JDBC编程-2SQL入门-2insert/select/update/delete
1. INSERT用于向数据库的表中插入1条记录 insert into 表名 (字段1,字段2,...) values (数据1,数据2,数据3...) 示例 -- 如果表存在,就删除 drop t ...
- 第十二章 Odoo 12开发之报表和服务端 QWeb
报表是业务应用非常有价值的功能,内置的 QWeb 引擎是报表的默认引擎.使用 QWeb 模板设计的报表可生成 HTML 文件并被转化成 PDF.也就是说我们可以很便捷地利用已学习的 QWeb 知识,应 ...
- 19-10-30-Night-V
看到$\text{V}$就想到了V神. 快快放假.... $\text{Vicetone}$最新单曲$\text{Aftermath}$大家听了嘛…… (真不是学数论之后的意思啊,译为‘后果’,显然是 ...
- iOS开发自定义转场动画
1.转场动画 iOS7之后开发者可以自定义界面切换的转场动画,就是在模态弹出(present.dismiss),Navigation的(push.pop),TabBar的系统切换效果之外自定义切换动画 ...
- 2019年6月份Github上最热门的开源项目排行出炉,一起来看看本月上榜的开源项目
6月份Github上最热门的开源项目排行出炉,一起来看看本月上榜的开源项目有哪些: 1. the-art-of-command-line https://github.com/jlevy/the-ar ...