理解javascript模块化


Posted in Javascript onMarch 28, 2016

模块化是一个通用的编程最佳实践。程序的模块化使我们可以更方便地使用别人的代码,想要什么功能,就加载什么模块,从而提高代码的利用效率,增加开发速度。

模块就像积木,有了它,我们可以搭出各种各种功能样式的程序。积木有什么特点?小而简单。同样的,我们程序中的模块也要做到这一点,确保自己创建的函数一次只完成一个工作,这样其他开发者可以简单地调试与修改你的代码,而不需浏览所有代码才能弄清每一个代码块执行了什么功能。只有做到像这样地小而简单,才能实现其通用功能。

一、javascript模块化的方法
1、函数封装
JavaScript的作用域就是基于函数的,所以我们可以把函数作为模块。

function fn1(){
  //code
}

function fn2(){
  //code
}

缺点:"污染"了全局变量,无法保证不与其他模块发生变量名冲突

2、对象

var myModule1 = {
  fn1: function(){
    //code
  },
  fn2: function(){
    //code
  }
}

缺点:会暴露所有模块成员,内部状态可以被外部改写

立即自执行函数——推荐

var myModule = (function(){
  function fn1(){
    //code
  },
  function fn2(){
    //code
  },
  return {
    fn1: fn1,
    fn2: fn2
  };
})();

二、小而简单
关于小而简单,我们看一个例子,比如我们现在想编写一个创建新链接的函数,并且为类型是"mailto"超链接添加一个class。可以这样做:

function addLink(text, url, parentElement) {
  var newLink = document.createElement('a');//创建a标签
  newLink.setAttribute('href', url);//为a标签设置href属性
  newLink.appendChild(document.createTextNode(text));//为a标签添加文本
  if(url.indexOf("mailto:")==-1){
    newLink.className = 'mail';
  }
  parentElement.appendChild(newLink);//将a标签添加到页面
}

这样写能够工作,但你或许会发现自己又不得进行其他的功能添加,于是,这个函数又不适用了。所以,函数越特殊,越难以适用于不同情形。
这里的函数写法没有达到模块化的要求——一个函数只干一件事。我们将函数改编下:

function createLink(text,url) {
  var newLink = document.createElement('a');
  newLink.setAttribute('href', url);
  newLink.appendChild(document.createTextNode(text));
  return newLink;
}

这里createLink函数只做一件事——创建并返回要添加到页面中的a标签(小而简单),这样我们就可以在任何需要创建超链接的情况下调用这样函数。

三、CommonJS
在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块与操作系统和其他应用程序互动,否则根本没法编程。虽然JavaScript在web端发展这么多年,但是第一个流行的模块化规范却由服务器端的JavaScript应用带来,CommonJS规范是由NodeJS发扬光大,这标志着JavaScript模块化编程正式登上舞台。
node.js的模块系统,就是依据CommonJS规范实现的。在CommonJS中,有一个全局性方法require(),用于加载模块。
加载模块:

var math = require('math');
调用模块:

  math.add(2,3)
CommonJS规范不适用于浏览器环境,因为它存在一个重大的局限,上例中第二行math.add(2, 3)必须要在math.js加载完成后才能运行,而模块都放在服务器端,所以可能要等很长时间,等待时间取决于网速的快慢。

CommonJS规范适用于服务器端,因为对于服务端来说,所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间

四、模块应该怎么定义和怎么加载?
AMD
Asynchronous Module Definition异步模块定义,主要代表:require.js
目的:
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。

1、定义模块

define(["./cart", "./inventory"], function(cart, inventory) {
  //通过[]引入依赖
  return {
    color: "blue",
    size: "large",
    addToCart: function() {
      inventory.decrement(this);
      cart.add(this);
    }
  }
}
);

2、加载模块

require( ["some/module", "my/module", "a.js", "b.js"],
function(someModule,  myModule) {
  //This function will be called when all the dependencies
  //listed above are loaded. Note that this function could
  //be called before the page is loaded.
  //This callback is optional.
}
 );

CMD
Common Module Definition通用模块定义,CMD规范是国内发展出来的。主要代表:sea.js

1、定义模块

define(function(require, exports, module) {
 // 通过 require 引入依赖
 var $ = require('jquery');
 var Spinning = require('./spinning');
 // 通过 exports 对外提供接口
 exports.doSomething = ...
 // 或者通过 module.exports 提供整个接口
 module.exports = ...
});

2、加载模块

seajs.use("../static/hello/src/main")
区别:

对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

CMD 推崇依赖就近,AMD 推崇依赖前置。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
Jquery操作radio的简单实例
Jan 06 Javascript
js实现点击获取验证码倒计时效果
Jan 28 Javascript
基于AngularJS实现iOS8自带的计算器
Sep 12 Javascript
javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)
Sep 20 Javascript
jquery实现折叠菜单效果【推荐】
Mar 08 Javascript
vue写一个组件
Apr 09 Javascript
vue-cli 3.0 自定义vue.config.js文件,多页构建的方法
Sep 19 Javascript
layui form表单提交后实现自动刷新
Oct 25 Javascript
Vue.js中的高级面试题及答案
Jan 13 Javascript
原生JS实现记忆翻牌游戏
Jul 31 Javascript
vue+element table表格实现动态列筛选的示例代码
Jan 14 Vue.js
Three.js实现雪糕地球的使用示例详解
Jul 07 Javascript
谈一谈jQuery核心架构设计
Mar 28 #Javascript
javascript函数自动执行常用方法汇总
Mar 28 #Javascript
JavaScript利用HTML DOM进行文档操作的方法
Mar 28 #Javascript
JavaScript常用本地对象小结
Mar 28 #Javascript
Bootstrap 粘页脚效果
Mar 28 #Javascript
jQuery实现的多滑动门,多选项卡效果代码
Mar 28 #Javascript
轻量级jQuery插件slideBox实现带底栏轮播(焦点图)代码
Mar 28 #Javascript
You might like
短波的认识
2021/03/01 无线电
关于使用key/value数据库redis和TTSERVER的心得体会
2013/06/28 PHP
php使用str_replace替换多维数组的实现方法分析
2017/06/15 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
javascript学习笔记--数字格式类型
2014/05/22 Javascript
取得元素的左和上偏移量的方法
2014/09/17 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
JavaScript对象数组排序实例方法浅析
2016/06/15 Javascript
微信小程序tabbar不显示解决办法
2017/06/08 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
[55:48]VGJ.S vs TNC Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
详解duck typing鸭子类型程序设计与Python的实现示例
2016/06/03 Python
浅谈python可视化包Bokeh
2018/02/07 Python
Django使用paginator插件实现翻页功能的实例
2018/10/24 Python
python读取word文档,插入mysql数据库的示例代码
2018/11/07 Python
Python类的继承、多态及获取对象信息操作详解
2019/02/28 Python
Python多项式回归的实现方法
2019/03/11 Python
pyqt5 从本地选择图片 并显示在label上的实例
2019/06/13 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
python按行读取文件并找出其中指定字符串
2019/08/08 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
浅谈pytorch、cuda、python的版本对齐问题
2020/01/15 Python
python sorted函数原理解析及练习
2020/02/10 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
面向中国市场的在线海淘美妆零售网站:Beauty House美丽屋
2021/03/02 全球购物
任课老师推荐信范文
2013/11/24 职场文书
数控专业大学毕业生职业规划范文
2014/02/06 职场文书
2014年乡镇植树节活动方案
2014/02/28 职场文书
个人借款担保书
2014/04/02 职场文书
客房部经理岗位职责
2015/02/02 职场文书
pycharm部署django项目到云服务器的详细流程
2021/06/29 Python
Python内置数据类型中的集合详解
2022/03/18 Python
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python