JavaScript 模块化编程(笔记)

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

第一章 JavaScript模块化编程

(一):模块的写法

一 原始写法
// 模块就是实现特定功能的一组方法;只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块;
    function m1(){
        // ...
    }
    function m2(){
        // ...
    }
// 上面的函数m1()和m2(),组成一个模块;使用时直接调用就行;
// 缺点:"污染"了全局变量; 无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系;

二 对象写法

// 把模块写成一个对象,所有的模块成员都放到这个对象里面;
  var module = new Object({
    _count:0,
    m1:function(){
      // ...
    },
    m2:function(){
      // ...
    }
  });
// 上面的函数m1()和m2(),都封装在module对象里;使用时直接调用这个对象的属性;
  module.m1();
// 但是,这样的写法会暴露所有模块成员,内部状态可以被外部改写;
  module._count = 4;

三 立即执行函数写法

  var module = (function(){
    var _count = 0;
    var m1 = function(){
      // ...
    };
    var m2 = function(){

    };
    return {
      m1:m1,
      m2:m2
    };
  })();
// 使用上面的写法,外部代码无法读取内部的_count变量;
  console.info(module._count); // undefined;
// 上面的写法就是JavaScript模块的基本写法;

四 放大模式

// 如果模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式";
  var module = (function(mod){
    mod.m3 = function(){
      // ...
    };
    return mod;
  })(module);
// 上面的代码为module模块添加了一个新方法m3(),然后返回新的module模块;

五 宽放大模式

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

六 输入全局变量

// 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互;
// 为了在模块内部调用全局变量,必须显式地将其他变量输入模块;
  var module = (function($,YAHOO){
    // ...
  })(jQuery,YAHOO);
// 上面的module模块需要使用jQuery库和YUI库,就把这两个库(其实是两个模块)当作参数输入module;
// 这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显;

第二章 JavaScript模块化编程(二):AMD规范

一 模块的规范
// 目前,通行的JavaScript模块规范共有两种:CommonJS和AMD;

二 CommonJS
// node.js将javascript语言用于服务器端编程,这标志"JavaScript模块化编程"正式诞生;
// node.js的模块系统,就是参照CommonJS规范实现的;
在CommonJS中,有一个全局性方法require(),用于加载模块;
    var math = require('math');        // 加载模块;
    math.add(2,3);                    // 调用模块方法=>5;

三 浏览器环境
// 上一节的代码在浏览器中运行会有很大的问题;
    var math = require('math');
    math.add(2,3);
// 问题:必须在require('math')等math.js加载完成,才会执行math.add(2,3);
// 所以浏览器的模块,不能采用"同步加载",只能采用"异步加载";==>AMD;

四 AMD
AMD(Asynchronous Module Definition)异步模块定义;
// 采用异步加载模块,模块的加载不影响它后面语句的运行,所有依赖这个模块的语句,都定义在一个回调函数中,
// 等加载完成之后,这个回调函数才会运行;
// AMD也采用require()语句加载模块,但是它要求两个参数:
    require([module],callback);
// module:是一个数组,里面的成员就是要加载的模块;
// callback:是加载成功之后的回调函数;
    require(['math'],function(math){
        math.add(2,3);
    });
// math.add()与math模块加载不是同步的,浏览器不会发生假死;所以,AMD比较适合浏览器环境;

第三章 JavaScript模块化编程(三):require.js的用法
一 为什么使用require.js
// 需要依次加载多个js文件;
// 缺点:
// 1.加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;
// 2.由于js文件之间存在依赖关系,因此必须严格保证加载顺序,当依赖关系很复杂的时候,代码的编写和维护都会变得困难;
// 所以require.js解决了这两个问题:
// 1.实现js文件的异步加载,避免网页失去响应;
// 2.管理模块之间的依赖性,便于代码的编写和维护;

二 require.js的加载
1.加载require.js
    <script scr="js/require.js" defer async="true"></script>
// async属性表明这个文件需要异步加载,避免网页失去响应;IE不支持这个属性,只支持defer,所以把defer也写上;
2.加载main.js
    <script src="js/require.js" data-main="js/main"></script>
// data-main属性的作用是,指定网页程序的主模块=>main.js,这个文件会第一个被require.js加载;
// 由于require.js默认的文件后缀名是js,所以可以把main.js简写成main;

三 主模块main.js的写法
1.如果main.js不依赖任何其他模块,可以直接写入JavaScript代码;
// main.js
    alert('加载成功!');
2.如果main.js依赖于模块,这时就要使用AMD规范定义的require()函数;
// main.js
    require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,moduleC){
        // ...
    })
// require()函数接收两个参数:
// 参数一:数组,表示所依赖的模块,即主模块依赖的三个模块;
// 参数二:回调函数,当前面指定的模块都加载成功后,它将被调用;加载的模块会以参数形式传入该函数,从而在回调函数内部可以使用这些模块;
// require()异步加载模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题;
实例:
    require(['jquery','underscore','backbone'],function($,_,Backbone){
        // ...
    });

四 模块的加载
// 使用require.config()方法,可以对模块的加载行为进行自定义;
// require.config()就写在主模块(main.js)的头部;
// 参数就是一个对象,这个对象的paths属性指定各个模块的加载路径;
// 设定以下三个模块的文件默认和main.js在用一个目录;
    require.config({
        paths:{
            "jquery":"jquery.min",
            "underscore":"underscore.min",
            "backbone":"backbone.min"
        }
    });

// 如果加载的模块和主模块不在同一个目录,就要逐一指定路径;
    require.config({
        paths:{
            "jquery":"lib/jquery.min",
            "underscore":"lib/underscore.min",
            "backbone":"lib/backbone.min"
        }
    });
// 或者直接改变基目录(baseUrl)
    require.config({
        baseUrl:"js/lib",
        paths:{
            "jquery":"jquery.min",
            "underscore":"underscore.min",
            "backbone":"backbone.min"
        }
    });

// 如果模块在另一台主机上,也可以直接指定它的网址
    require.config({
        paths:{
            "jquery":"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
        }
    });
// require.js要求,每个模块是一个单独的js文件;这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度;
// 因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数;

五 AMD模块的写法

// require.js加载的模块,采用AMD规范,也就是说,模块必须按照AMD的规定来写;
// 具体来说,就是模块必须采用特定的define()函数来定义;如果一个模块不依赖其他模块,那么可以直接定义在define()函数中;
// 在math.js中定义math模块
// math.js
    define(function(){
        var add = function(x,y){
            return x+y;
        };
        return {
            add:add
        };
    });
// 在main.js中加载math模块
    require(['math'],function(math){
        alert(math.add(1,1));
    });
// 如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性;
// math.js
    define(['myLib'],function(myLib){
        function foo(){
            myLib.doSomething();
        }
        return {
            foo:foo
        };
    });
// 当require()函数加载上面这个模块的时候,就会先加载myLib.js文件;

六 加载非规范的模块

// 加载非规范的模块,在用require()加载之前,要先用require.config()方法,定义它们的一些特征;
    require.config({
        shim:{
            'underscore':{
                exports:'_'
            },
            'backbone':{
                deps:['underscore','jquery'],
                exports:'Backbone'
            }
        }
    });
// require.config()接收一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块;
// (1).定义deps数组,表明该模块的依赖性;
// (2).定义exports值(输出的变量名),表明这个模块外部调用时的名称;
比如:jQuery的插件
    shim:{
        'jquery.scroll':{
            deps:['jquery'],
            exports:'jQuery.fn.scroll'
        }
    };

七 require.js插件

1.domready:可以让回调函数在页面DOM结构加载完成之后运行;
    require(['domready!'],function(doc){
        // called once the DOM is ready;
    })   
2.text和image:允许require.js加载文本和图片文件;
    define(['text!review.txt','image!cat.jpg'],function(review,cat){
        console.log(review);
        document.body.appendChild(cat);
    });

(0)

相关推荐

  • 详解Js中的模块化是如何实现的

    由于 Js 起初定位的原因(刚开始没想到会应用在过于复杂的场景),所以它本身并没有提供模块系统,随着应用的复杂化,模块化成为了一个必须解决的问题.本着菲麦深入原理的原则,很有必要来揭开模块化的面纱 一.模块化需要解决的问题 要对一个东西进行深入的剖析,有必要带着目的去看.模块化所要解决的问题可以用一句话概括 在没有全局污染的情况下,更好的组织项目代码 举一个简单的栗子,我们现在有如下的代码: function doSomething () { const a = 10; const b = 11

  • 轻松创建nodejs服务器(3):代码模块化

    nodejs的功能块大都以模块的形式存在的. 通常会有一个统一入口index.js,然后调用不同的模块来完成我们需要的功能. 我们先来看看怎么把server.js变成一个模块让 index.js 主文件使用. 复制代码 代码如下: var http = require("http"); ... http.createServer(...); "http" 是nodejs自带的模块,我们在我们的代码中请求它并把返回值赋给一个本地变量. 我们可以用这个变量来调用 htt

  • Javascript模块化编程(三)require.js的用法及功能介绍

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js.  一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代码,相信很多人都见过. 复制代码 代码如下: <script src="1.js"></script> &l

  • 详解JavaScript模块化开发

    什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前端开发得到重视,也使得前端项目越来越复杂,然而,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,那么什么是模块呢? 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.模块开发

  • javascript模块化是什么及其优缺点介绍

    如今backbone.emberjs.spinejs.batmanjs 等MVC框架侵袭而来.CommonJS.AMD.NodeJS.RequireJS.SeaJS.curljs等模块化的JavaScript扑面而来.web前端已经演变成大前端,web前端的发展速度之快. 1)我们来看看什么是模块化? 模块化是一种将系统分离成独立功能部分的方法,可将系统分割成独立的功能部分,严格定义模块接口.模块间具有透明性.javascript中的模块在一些C.PHP.java中比较常见: c中使用inclu

  • Javascript模块化编程详解

    模块化编程是一种非常常见Javascript编程模式.它一般来说可以使得代码更易于理解,但是有许多优秀的实践还没有广为人知. 基础 我们首先简单地概述一下,自从三年前Eric Miraglia(YUI的开发者)第一次发表博客描述模块化模式以来的一些模块化模式.如果你已经对于这些模块化模式非常熟悉了,大可以直接跳过本节,从"进阶模式"开始阅读. 匿名闭包 这是一种让一切变为可能的基本结构,同时它也是Javascript最棒的特性.我们将简单地创建一个匿名函数并立即执行它.所有的代码将跑在

  • Javascript模块化编程(一)模块的写法最佳实践

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂.  网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑. Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. 但是,Javascript不是一种模块化编程语言,它不支持"类"(class),更遑论"模块&

  • JavaScript的模块化:封装(闭包),继承(原型) 介绍

    虽然 JavaScript 天生就是一副随随便便的样子,但是随着浏览器能够完成的事情越来越多,这门语言也也越来越经常地摆出正襟危坐的架势.在复杂的逻辑下, JavaScript 需要被模块化,模块需要封装起来,只留下供外界调用的接口.闭包是 JavaScript 中实现模块封装的关键,也是很多初学者难以理解的要点.最初,我也陷入迷惑之中.现在,我自信对这个概念已经有了比较深入的理解.为了便于理解,文中试图封装一个比较简单的对象. 我们试图在页面上维护一个计数器对象 ticker ,这个对象维护一

  • JavaScript 模块化编程(笔记)

    一直对JS都是一知半解,最近遇到这方面问题,所以在网上学习了一下,现在还没有完全明白,先贴出笔记; 第一章 JavaScript模块化编程 (一):模块的写法 一 原始写法 // 模块就是实现特定功能的一组方法;只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块;     function m1(){         // ...     }     function m2(){         // ...     } // 上面的函数m1()和m2(),组成一个模块;使用时

  • Javascript模块化编程(一)AMD规范(规范使用模块)

    这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块.  (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块. 但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套!考虑到Javascript模块现在还没有官方规范,这一点就更重要了. 目前,通行的Javascript模块规范共有两种:CommonJS和AMD.我主要介绍AMD,

  • 论JavaScript模块化编程

    JavaScript模块化编程的重要性 JavaScript的原型是java,它也是一种面向对象编程语言,属于一种弱类型语言,它具有更大的灵活性.以往在编写javascript代码时,都是直接编写一个个.js文件,然后用script标签在html页面中引用,这样就会带来几方面的问题: 1.出现大量的全局变量 js在每个地方都可以定义一个全局变量,编写不符合规范将导致大量全局变量的出现,最终程序将难以维护. 2.js加载顺序要按照代码的依赖顺序 最简单的,例如a.js依赖于b.js文件,那么在ht

  • 理解javascript模块化

    模块化是一个通用的编程最佳实践.程序的模块化使我们可以更方便地使用别人的代码,想要什么功能,就加载什么模块,从而提高代码的利用效率,增加开发速度. 模块就像积木,有了它,我们可以搭出各种各种功能样式的程序.积木有什么特点?小而简单.同样的,我们程序中的模块也要做到这一点,确保自己创建的函数一次只完成一个工作,这样其他开发者可以简单地调试与修改你的代码,而不需浏览所有代码才能弄清每一个代码块执行了什么功能.只有做到像这样地小而简单,才能实现其通用功能. 一.javascript模块化的方法 1.函

  • 《JavaScript高级编程》学习笔记之object和array引用类型

    本文给大家分享我的javascript高级编程学习笔记之object和array引用类型,涉及到javascript引用类型相关知识,大家一起看看把. 1. Object类型 大多数引用类型值都是Object类型的实例:而且Object也是ECMAScript中使用最多的一个类型. 创建Object实例有如下两种方式: new操作符后跟Object构造函数: var person=new Object( ); person.name="webb"; person.age=25; 对象字

  • 《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史

    JavaScript 是Netscape公司与Sun公司合作开发的.在 JavaScript 1.0发布时,Netscape Navigator主宰着浏览器市场.微软在推出IE3的时候发布了自己的VBScript语言,同时以JScript为名发布了JavaScript 的一个版本,很快赶上了 Netscape 的步伐.面对微软公司的竞争,Netscape 和 Sun公司联合ECMA(欧洲计算机制造商协会)对JavaScript 语言进行了标准化,于是出现了ECMAScript语言,这是同一种语言

  • javascript异步编程代码书写规范Promise学习笔记

    最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下. 一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编程时候代码书写的方式产生的. 随着javascript的发展,异步的场景越来越多.前端有AJAX,setTimeout等,后端Node异步更多.按照传统的做法,那么就是各种回调嵌回调.代码可以把人绕晕. 这个时候,CommonJS社区提出了一个叫做Promise/A+的规范,这个规范定义了如何书写异步代

随机推荐