zoukankan      html  css  js  c++  java
  • JavaScript--模块化编程(笔记)

    一直对JS都是一知半解,最近遇到这方面问题,所以在网上学习了一下,现在还没有完全明白,先贴出笔记;

      1 第一章 JavaScript模块化编程(一):模块的写法
      2 
      3 一 原始写法
      4 // 模块就是实现特定功能的一组方法;只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块;
      5     function m1(){
      6         // ...
      7     }
      8     function m2(){
      9         // ...
     10     }
     11 // 上面的函数m1()和m2(),组成一个模块;使用时直接调用就行;
     12 // 缺点:"污染"了全局变量; 无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系;
     13 
     14 二 对象写法
     15 // 把模块写成一个对象,所有的模块成员都放到这个对象里面;
     16     var module = new Object({
     17         _count:0,
     18         m1:function(){
     19             // ...
     20         },
     21         m2:function(){
     22             // ...
     23         }
     24     });
     25 // 上面的函数m1()和m2(),都封装在module对象里;使用时直接调用这个对象的属性;
     26     module.m1();
     27 // 但是,这样的写法会暴露所有模块成员,内部状态可以被外部改写;
     28     module._count = 4;
     29 
     30 三 立即执行函数写法
     31     var module = (function(){
     32         var _count = 0;
     33         var m1 = function(){
     34             // ...
     35         };
     36         var m2 = function(){
     37 
     38         };
     39         return {
     40             m1:m1,
     41             m2:m2
     42         };
     43     })();
     44 // 使用上面的写法,外部代码无法读取内部的_count变量;
     45     console.info(module._count);  // undefined;
     46 // 上面的写法就是JavaScript模块的基本写法;
     47 
     48 四 放大模式
     49 // 如果模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式";
     50     var module = (function(mod){
     51         mod.m3 = function(){
     52             // ...
     53         };
     54         return mod;
     55     })(module);
     56 // 上面的代码为module模块添加了一个新方法m3(),然后返回新的module模块;
     57 
     58 五 宽放大模式
     59 // 在浏览器环境中,模块的各个部分通常都是从网上获取的,有时无法知道哪个部分会先加载;
     60 // 如果采用上一节的写法,第一个执行的部分有可能加载一个不存在的空对象,这时就要采用"宽放大模式";
     61     var module = (function(mod){
     62         // ...
     63         return mod;
     64     })(window.module || {});
     65 // 与"放大模式"相比,"宽放大模式"就是"立即执行函数"的参数可以是空对象;
     66 
     67 六 输入全局变量
     68 // 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互;
     69 // 为了在模块内部调用全局变量,必须显式地将其他变量输入模块;
     70     var module = (function($,YAHOO){
     71         // ...
     72     })(jQuery,YAHOO);
     73 // 上面的module模块需要使用jQuery库和YUI库,就把这两个库(其实是两个模块)当作参数输入module;
     74 // 这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显;
     75 
     76 第二章 JavaScript模块化编程(二):AMD规范
     77 
     78 一 模块的规范
     79 // 目前,通行的JavaScript模块规范共有两种:CommonJS和AMD;
     80 
     81 二 CommonJS
     82 // node.js将javascript语言用于服务器端编程,这标志"JavaScript模块化编程"正式诞生;
     83 // node.js的模块系统,就是参照CommonJS规范实现的;
     84 在CommonJS中,有一个全局性方法require(),用于加载模块;
     85     var math = require('math');        // 加载模块;
     86     math.add(2,3);                    // 调用模块方法=>5;
     87 
     88 三 浏览器环境
     89 // 上一节的代码在浏览器中运行会有很大的问题;
     90     var math = require('math');
     91     math.add(2,3);
     92 // 问题:必须在require('math')等math.js加载完成,才会执行math.add(2,3);
     93 // 所以浏览器的模块,不能采用"同步加载",只能采用"异步加载";==>AMD;
     94 
     95 四 AMD
     96 AMD(Asynchronous Module Definition)异步模块定义;
     97 // 采用异步加载模块,模块的加载不影响它后面语句的运行,所有依赖这个模块的语句,都定义在一个回调函数中,
     98 // 等加载完成之后,这个回调函数才会运行;
     99 // AMD也采用require()语句加载模块,但是它要求两个参数:
    100     require([module],callback);
    101 // module:是一个数组,里面的成员就是要加载的模块;
    102 // callback:是加载成功之后的回调函数;
    103     require(['math'],function(math){
    104         math.add(2,3);
    105     });
    106 // math.add()与math模块加载不是同步的,浏览器不会发生假死;所以,AMD比较适合浏览器环境;
    107 
    108 第三章 JavaScript模块化编程(三):require.js的用法
    109 一 为什么使用require.js
    110 // 需要依次加载多个js文件;
    111 // 缺点:
    112 // 1.加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;
    113 // 2.由于js文件之间存在依赖关系,因此必须严格保证加载顺序,当依赖关系很复杂的时候,代码的编写和维护都会变得困难;
    114 // 所以require.js解决了这两个问题:
    115 // 1.实现js文件的异步加载,避免网页失去响应;
    116 // 2.管理模块之间的依赖性,便于代码的编写和维护;
    117 
    118 二 require.js的加载
    119 1.加载require.js
    120     <script scr="js/require.js" defer async="true"></script>
    121 // async属性表明这个文件需要异步加载,避免网页失去响应;IE不支持这个属性,只支持defer,所以把defer也写上;
    122 2.加载main.js
    123     <script src="js/require.js" data-main="js/main"></script>
    124 // data-main属性的作用是,指定网页程序的主模块=>main.js,这个文件会第一个被require.js加载;
    125 // 由于require.js默认的文件后缀名是js,所以可以把main.js简写成main;
    126 
    127 三 主模块main.js的写法
    128 1.如果main.js不依赖任何其他模块,可以直接写入JavaScript代码;
    129 // main.js
    130     alert('加载成功!');
    131 2.如果main.js依赖于模块,这时就要使用AMD规范定义的require()函数;
    132 // main.js
    133     require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,moduleC){
    134         // ...
    135     })
    136 // require()函数接收两个参数:
    137 // 参数一:数组,表示所依赖的模块,即主模块依赖的三个模块;
    138 // 参数二:回调函数,当前面指定的模块都加载成功后,它将被调用;加载的模块会以参数形式传入该函数,从而在回调函数内部可以使用这些模块;
    139 // require()异步加载模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题;
    140 实例:
    141     require(['jquery','underscore','backbone'],function($,_,Backbone){
    142         // ...
    143     });
    144 
    145 四 模块的加载
    146 // 使用require.config()方法,可以对模块的加载行为进行自定义;
    147 // require.config()就写在主模块(main.js)的头部;
    148 // 参数就是一个对象,这个对象的paths属性指定各个模块的加载路径;
    149 // 设定以下三个模块的文件默认和main.js在用一个目录;
    150     require.config({
    151         paths:{
    152             "jquery":"jquery.min",
    153             "underscore":"underscore.min",
    154             "backbone":"backbone.min"
    155         }
    156     });
    157 
    158 // 如果加载的模块和主模块不在同一个目录,就要逐一指定路径;
    159     require.config({
    160         paths:{
    161             "jquery":"lib/jquery.min",
    162             "underscore":"lib/underscore.min",
    163             "backbone":"lib/backbone.min"
    164         }
    165     });
    166 // 或者直接改变基目录(baseUrl)
    167     require.config({
    168         baseUrl:"js/lib",
    169         paths:{
    170             "jquery":"jquery.min",
    171             "underscore":"underscore.min",
    172             "backbone":"backbone.min"
    173         }
    174     });
    175 
    176 // 如果模块在另一台主机上,也可以直接指定它的网址
    177     require.config({
    178         paths:{
    179             "jquery":"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
    180         }
    181     });
    182 // require.js要求,每个模块是一个单独的js文件;这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度;
    183 // 因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数;
    184 
    185 五 AMD模块的写法
    186 // require.js加载的模块,采用AMD规范,也就是说,模块必须按照AMD的规定来写;
    187 // 具体来说,就是模块必须采用特定的define()函数来定义;如果一个模块不依赖其他模块,那么可以直接定义在define()函数中;
    188 // 在math.js中定义math模块
    189 // math.js
    190     define(function(){
    191         var add = function(x,y){
    192             return x+y;
    193         };
    194         return {
    195             add:add
    196         };
    197     });
    198 // 在main.js中加载math模块
    199     require(['math'],function(math){
    200         alert(math.add(1,1));
    201     });
    202 // 如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性;
    203 // math.js
    204     define(['myLib'],function(myLib){
    205         function foo(){
    206             myLib.doSomething();
    207         }
    208         return {
    209             foo:foo
    210         };
    211     });
    212 // 当require()函数加载上面这个模块的时候,就会先加载myLib.js文件;
    213 
    214 六 加载非规范的模块
    215 // 加载非规范的模块,在用require()加载之前,要先用require.config()方法,定义它们的一些特征;
    216     require.config({
    217         shim:{
    218             'underscore':{
    219                 exports:'_'
    220             },
    221             'backbone':{
    222                 deps:['underscore','jquery'],
    223                 exports:'Backbone'
    224             }
    225         }
    226     });
    227 // require.config()接收一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块;
    228 // (1).定义deps数组,表明该模块的依赖性;
    229 // (2).定义exports值(输出的变量名),表明这个模块外部调用时的名称;
    230 比如:jQuery的插件
    231     shim:{
    232         'jquery.scroll':{
    233             deps:['jquery'],
    234             exports:'jQuery.fn.scroll'
    235         }
    236     };
    237 
    238 七 require.js插件
    239 1.domready:可以让回调函数在页面DOM结构加载完成之后运行;
    240     require(['domready!'],function(doc){
    241         // called once the DOM is ready;
    242     })    
    243 2.text和image:允许require.js加载文本和图片文件;
    244     define(['text!review.txt','image!cat.jpg'],function(review,cat){
    245         console.log(review);
    246         document.body.appendChild(cat);
    247     });

     学习来源:Javascript模块化编程

  • 相关阅读:
    记录一次 Linux crontab 执行django 脚本 失败 的经历和解决办法
    python3 使用 django-xadmin 遇到的许多坑
    简要说明 django restframework 的交互式文档
    No application found. Either work inside a view function or push an application context.
    解决Docker容器内访问宿主机MySQL数据库服务器的问题
    《计算机网络自顶向下方法-第七版》第三章总结
    《计算机网络自顶向下方法-第七版》第七章总结
    《计算机网络自顶向下方法-第七版》第二章总结
    《计算机网络自顶向下方法-第七版》第一章总结
    深入理解Docker容器执行引擎runC
  • 原文地址:https://www.cnblogs.com/yizihan/p/4331852.html
Copyright © 2011-2022 走看看