Javascript 模块化编程 --RequireJs
什么是模块化
模块就是实现特定功能的一组方法,常见的几种js写法
- 原始写法
  function A() {
        }
 function B() {
  }
上面函数A()和B()组成一个模块,使用的时候直接调用就行了
缺点: “污染”了全局变量,模块成员之间没有直接的联系。
- 对象写法
var module= {
         count:,
         A: function() {
         },
         B: function() {
         }
       }
这种写法把变量count和函数A和 B 都封装到了module中,使用的时候直接调用,例如:
Module.A();
缺点:这种做法暴露了模块成员,内部的变量可以被外部改写,例如:
Module.count=5
- 立即执行函数写法
var modulel = (function() {
            var count = 5;
            var A = function() {
                console.log("function A");
            };
            var B = function() {
                console.log("function B");
            };
            return {
                A:A,
                B:B,
                count:count
            }
        })();
- 放大模式
如果一个模块很大,必须分成几个部分,则需要继承另外一个模块,则有必要使用“放大模式”
var commonUtil = (function (util) {
            util.m1 = function () {
                console.log("m1 function");
            };
            util.m2 = function () {
                console.log("m2 function");
            };
            util.count = 5;
            return util;
        })(commonUtil);
        console.log(commonUtil.m1());
        console.log(commonUtil.count);
- 宽放大模式
var commonUtil = (function (util) {
            util.m1 = function () {
               console.log("m1 function");
            };
            util.m2 = function () {
                console.log("m2 function");
            };
            util.count = 5;
            return util;
        })(commonUtil || {});
        console.log(commonUtil.m1());
        console.log(commonUtil.count);
与“放大模式”相比,“宽放大模式”就是立即执行函数可以是空对象
为什么要用require.js
最早的时候,所有的javascript都是写在一个文件中,代码越来越多,则分成了多个,例如:
<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
<script src="5.js"></script>
<script src="6.js"></script>
这样做的缺点:
1)加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就越长
2)必须保证加载的顺序,依赖最大的模块一定要放到最后加载
Require.js就是为了解决这两个问题:
1) 实现js文件的异步加载,避免网页失去响应
2) 管理模块之间的依赖性,便于代码的编写和维护
Require.js加载
首先要到官方网站下载最新版本http://requirejs.org/docs/download.html放到Scripts目录下
然后在页面加载,例如:
<script src="Scripts/require.js"></script>
加载这个文件也有可能造成网页失去响应,解决办法有两个,一是把它放在网页底部加载,另外一个是写成这样:
<script src="Scripts/require.js" defer async="true" ></script>
Async表示是异步加载,ie不支持这个属性,只支持defer,所以把defer也写上
加载require.js之后,则是加载我们自己的代码了,假如我们自己的代码文件是main.js,则需要写成这样
<script src="Scripts/require.js" data-main="Scripts/main.js"></script>
data-main属性的作用是指定网页程序的主模板,就是网页的入口代码,有点像控制台程序的main()函数,所有的代码都是从这里开始运行
模块的加载
假如模块依赖’jquery’,’underscore’,’backbone’,则需要在require.config()方法中对这些模块进行配置
我们可以把require.config()写在主模块main.js的头部,也可以新建一个require_config.js文件把这些配置写在这个文件中,然后在页面引用这个文件,例如:
(function () {
    var baseurl = "/Scripts/";
    require.config({
        paths: {
            "jquery": baseurl+"jquery",
            "underscore": baseurl+"underscore",
            "backbone": baseurl+"backbone",
            "index":baseurl+"lib/index"
        },
        shim: {
            'underscore': {
               exports: '_'
            },
            'backbone': {
                deps: ['underscore', 'jquery'],
                exports: 'Backbone'
            }
        }
    });
})();
如果某个模块在另外的主机上,也可以指定网址,例如:
require.config({
        paths: {
            "jquery":”https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min”,
        }
    });
require.js加载的模块,必须按照AMD规范,用define()函数定义的模块。但有一部分函数库并不符合这种规范,这种模块则必须在require()加载前,用shim属性进行配置,shim属性是用来配置不兼容的模块。
例如:
   shim: {
            'underscore': {
                exports: '_'
            },
            'backbone': {
                deps: ['underscore', 'jquery'],
                exports: 'Backbone'
          }
        }
其中
1) exports表示输出变量名,即在模块外部调用的名称
2) deps数组,表示该模块的依赖性
主模块的写法
require()函数接受两个参数,第一个参数是一个数组,表示所依赖的模块,第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数的形式传入该函数,而在回调函数中就可以使用这些模块了。
例如:主模块依赖jquery,underscore和backbone这三个模块,main.js就可以这样写:
require (['jquery', 'underscore', 'backbone'], function ($, _, Backbone) {
   //some code here
});
require.js会先加载jQuery,underscore和backbone,然后再运行回调函数,主模块的代码就写在回调函数中
AMD模块的写法
require.js加载的模块,采用AMD规范,模块也必须按照AMD来写,就是模块必须采用特定的define函数来定义,例如math.js:
define(function() {
            var add = function(x, y) {
                return x + y;
            };
            return add;
        });
然后在require_config.js的path中进行定义,例如:
(function () {
    var baseurl = "/Scripts/";
    require.config({
        paths: {
            "math":baseurl+"lib/math"
        },
    });
})();
之后再在页面对这个math模块进行加载,如:
require(['math'], function(math) {
           console.log(math.add(3,5));
        });
例如利用require.js模块化写一个简单的banckbone例子,index.htm代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>我的第一个backbone的例子</title>
</head>
<body>
<button id="check">新手报到</button>
<ul id="world-list"> </ul>
<script src="../../Scripts/require.js" data-main="../../Scripts/lib/index.js"></script>
<script src="../../Scripts/require_config.js"></script>
<script>
require(['index'], function(indexView) {
var app = indexView.AppView;
var AppView = new app;
});
</script>
</body>
</html>
require_config.js配置如下:
(function () {
    var baseurl = "/Scripts/";
    require.config({
        paths: {
            "jquery": baseurl+"jquery",
            "underscore": baseurl+"underscore",
            "backbone": baseurl+"backbone",
            "index":baseurl+"lib/index"
        },
        shim: {
            'underscore': {
                exports: '_'
            },
            'backbone': {
                deps: ['underscore', 'jquery'],
                exports: 'Backbone'
            }
        }
    });
})();
index.js文件的代码如下:
define(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) {
    var listView = {
        World: Backbone.Model.extend({
            name: null
        }),
        Worlds: Backbone.Collection.extend({
            initialize: function(models, options) {
                this.bind("add", options.view.addOneWord);
            }
        }),
        AppView: Backbone.View.extend({
            el: $("body"),
            initialize: function() {
                this.worlds = new listView.Worlds(null, { view: this });
            },
            events: {
                "click #check": "checkIn"
            },
            checkIn: function() {
                var world_name = prompt("请问你是哪里人");
                if (world_name == "") world_name = "未知";
                var world = new listView.World({ name: world_name });
                this.worlds.add(world);
            },
            addOneWord: function (model) {
                $("#world-list").append("<li>我是来自:" + model.get("name") + "的人!</li>");
            }
        })
    };
    return listView;
});
define和require加载的区别
Define和require在依赖处理和回调执行上是一样的,但是define回调的函数需要有return语句返回模块对象,这样define定义的模块才能被其他模块调用;require回调函数不需要有return语句。所以说define和require都可应用来加载和使用模块,但是define可以用来定义模块,用define定义的模块必须要有返回值
Javascript 模块化编程 --RequireJs的更多相关文章
- Javascript模块化编程require.js的用法
		JS模块化工具requirejs教程(一):初识requirejs http://www.runoob.com/w3cnote/requirejs-tutorial-1.html JS模块化工具req ... 
- 应用require.js进行javascript模块化编程小试一例
		长久以来都渴望应用javascript的模块化编程.今日紧迫更甚,岁月蹉跎,已经不能再等了. 拜读阮一峰的有关文章已经好几遍,文章写得真好,简洁流畅,头头是道,自觉有点明白了.但经验告诉我们,一定要亲 ... 
- javascript模块化编程思想、实现与规范
		随着BS架构的发展,网站逐渐变成了互联网应用程序,嵌入网络的JavaScript代码越来越庞大,越来越复杂(业务逻辑处理或用户交互很多写在前端).网页越来越像桌面程序,需要一个团队分工协作.进度管理. ... 
- 简述JavaScript模块化编程(一)
		在早期编写JavaScript时,我们只需在<script>标签内写入JavaScript的代码就可以满足我们对页面交互的需要了.但随着时间的推移,时代的发展,原本的那种简单粗暴的编写方式 ... 
- Javascript模块化编程(三):require.js的用法
		Javascript模块化编程(三):require.js的用法 原文地址:http://www.ruanyifeng.com/blog/2012/11/require_js.html 作者: 阮一峰 ... 
- Javascript模块化编程(二):AMD规范
		Javascript模块化编程(二):AMD规范 作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_d ... 
- Javascript模块化编程(一):模块的写法
		Javascript模块化编程(一):模块的写法 作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html ... 
- Javascript模块化编程(二):AMD规范(转)
		这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要 ... 
- Javascript模块化编程(一):模块的写法(转)
		随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者 ... 
随机推荐
- Android控件ListView获取item中EditText值
			能够明白,如今没有直接方法能够获得ListView中每一行EditText的值. 解决方式:重写BaseAdapter,然后自行获取ListView中每行输入的EditText值. 大概算法:重写Ba ... 
- 使用虚拟环境 virtualenv
			1.安装 $ sudo apt-get install python-virtualenv 2.重命名,一般虚拟环境会被命名为venv $ virtualenv venv 3. 激活 $ sour ... 
- 【SQLServer2008】之Telnet以及1433端口设置
			Telnet步骤: 一.首先进入Win7控制面板,可以从开始里找到或者在桌面上找到计算机,点击进入里面也可以找到控制面板,如下图: 二.进入控制面板后,我们再找到“程序和功能”并点击进入,如下图所示: ... 
- Solr In Action 中文版 第一章(四、五)
			1.1 功能概览1. 4 最后,让我们再依照以下的分类.高速的过一下Solr的主要功能: ·用户体验 ·数据建模 ·Solr 4的新功能 在本书中.为你的用户提供良好的搜索体验 ... 
- 网站存储session的方案
			1: ASP.NET State Service是什么 用来管理 Session 的,正常来说,Session 位于IIS进程中(其实可以理解成在服务器的内存中),当IIS重启或程序池回收会自动清空S ... 
- 九度OJ 1337:寻找最长合法括号序列 (DP)
			时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:839 解决:179 题目描述: 给你一个长度为N的,由'('和')'组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的 ... 
- mysql数据库访问授权
			1.进入MySQL服务器 d:\mysql\bin\> mysql -h localhost -u root; 2.赋予任何主机访问数据的权限 mysql> GRANT ALL PRIVI ... 
- Centos设置开机启动Apache和Mysql
			先用chkconfig --list查询apache和mysql服务是否存在,不存在则需要手动添加 [root@centos64 vsftpd]# chkconfig --list 测试存在,只需要开 ... 
- 1.搭建Django开发环境
			1.安装python(版本3.5.1) 官网下载:https://www.python.org/downloads/release/python-351/2.更新pip 命令:python -m pi ... 
- 使用OpenSSL工具制作X.509证书的方法及其注意事项总结
			版权声明:本文为博主原创文章.转载请注明出处. https://blog.csdn.net/Ping_Fani07/article/details/21622545 怎样使用OpenSSL工具生成根证 ... 
