zoukankan      html  css  js  c++  java
  • 我也谈 javascript 模块化 -AMD规范

    最近,读了很多有关js模块化编程方面的文章,自己也有些小小的理解,不过,还是得借助别人的总结,在这个基础上谈一谈自己的理解吧!
    参考:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html
    1、网页js程序为什么要模块化?
    ;之前做的一些网站,或者说网页,基本上是一html+css实现布局,内容展示为主。至于一些表单的验证逻辑,以及给页面实现一些特效(比如点击之后弹个窗出来,动画啊,等等)之类的,无非就是在对应的页面中写一些js脚本就好了,哪个页面要什么功能,就写一些js脚本到这个页面中就好了。整个网站下来,每个页面都有对应的js文件,感觉不好管理,没有系统化。而且,对于有些页面功能比较多,可能这个页面的js文件就比较多,代码可能就会更加复杂一点了。 再进一步,如果想在一个页面中做更多更多的功能,更多的交互,那显然这个页面的js代码量是非常多的。  要在一个html网页中实现像我们的客户端软件类似的功能,我们的网站,或者说网页就叫做 SPA --singal page application 单页面应用了。
    这个时候js代码是非常多的,而且js代码之间免不了互相依赖,先执行与后执行的关系存在。这个时候,就有管理我们的js文件的必要了。
    2、所以,出于这样的情况,就出现了js的模块化。

    “模块”,模块就是实现特定的功能的一组方法。
    只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。

    一、原始写法
    function m1(){
    //...
    }
    function m2(){
    //....
    }
    上面的函数m1()和m2(),组成一个模块,使用的时候,直接调用就行了。
    这种做法的缺点很明显,“污染了全局变量”,即很容易导致命名冲突,而且全局变量
    一直存在,不会销毁,占用内存,很容易造成内存泄露。而且模块的成员直接看不出
    直接的关系。

    二、对象写法
    为了解决上面的缺点,可以吧模块写成一个对象,所有的模块成员都放在这个对象里面。
    var module1 = new Object({
    _count: 0,
    m1 : function(){
    //...
    },
    m2 : function(){
    //...
    }
    });
    上面的函数m1()和m2(), 都封装在module1对象里,使用的时候,就调用这个对象的属性。
    module1.m1();
    但是,这样的写法会暴露所有的模块成员,内部状态可以被外部改写。比如,外部代码可以
    直接改写内部计数器的值,
    module1._count = 5;

    三、立即执行函数写法

    var module1 = (function (){
    var _count = 0;
    var m1 = function(){
    //..
    };
    var m2 = function(){
    //...
    };
    return {
    m1: m1,
    m2: m2
    }
    })();
    使用这种写法,外部代码无非读取内部的_count变量的值。
    console.info(module._count);//undefined

    module1就是Javascript 模块的基本写法。下面,在对这种写法进行加工。

    四、放大模式

    如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这是就必须
    采用放大模式(sugmentation)

    var module1 = (function(mod){
    mod.m3 = function(){
    //...
    };
    })(module1);
    上面的代码为module1模块添加了一个新方法m3();,然后返回新的module1模块;

    五、宽放大模式(Loose augmentation)

    在浏览器环境中,模块的各个部分通常都是从网上获取的,又是无法知道哪个会先加载。
    如果采用上一节的写法,第一个执行的部分可能加载一个不存在的空对象,这是就要采用
    “宽放大模式”
    var module1 = (function(mod){
    //return mod;
    })(window.module1 || {});
    与“放大模式”相比,“宽放大模式”就是“立即执行函数的参数”可以是空对象。

    六、输入全局变量

    独立性是模块的重要特点,模块内部最好不予程序的其他部分直接交互。
    为了在模块内部调用全局变量,必须显示地将其他变量输入模块。
    var module1 = (function($, YAHOO){
    //...
    })(jQuery, YAHOO);
    上面的module1 模块需要使用jQuery库和YUI 库,就把这两个库(其实是两个模块)当做参数
    传入module1,这样做出了保证模块的独立性,还是模块之间的依赖关系变得明显。这方面的讨论
    参考Ben cherry 的著名文章《Javascript Module Pattern: In-Depth》.

  • 相关阅读:
    利用WinCE的精准计时函数来输出pwm信号以便控制舵机
    leafletjs旋转marker
    centos7 NodeJs安装问题:Error: Cannot find module '../lib/utils/unsupported.js'
    Django 自定义存储上传文件的文件名
    后端开发不会前端之表格插件的使用
    Django项目部署之sqlite版本升级
    SQL 循环30日
    SSRS 报表 报表迁移
    SQL SERVER中求上月、本月和下月的第一天和最后一天
    SSRS 报表 日期类表达式
  • 原文地址:https://www.cnblogs.com/oxspirt/p/4521256.html
Copyright © 2011-2022 走看看