zoukankan      html  css  js  c++  java
  • Javascript的模块化编程

    Javascript在设计之初并没有提供一种原生的,语言级别的模块化方式来组织代码,比如Java语言通过package和import来管理和使用模块。ECMAScript 6引入了class和import的概念来支持模块化,但是浏览器全面支持这个标准还需要很长时间。

    应用程序的模块化指的就是通过一些高度解耦的,存放在不同地方的功能模块构成。近年来随着Javascript应用的复杂化,大型化,Javascript代码需要更为有序的组织,在Javascript社区出现了很多种模块化的实现方式,最主要的两个规范是CommomJS和AMD,本文会重点阐述这两个规范。

    1. CommonJS

    CommonJS是以在浏览器之外构建Javascript系统而产生的项目,致力于Javascript模块的标准化工作。主要特点是同步加载Javascript模块,运行在服务器端。Node.js 就是CommonJS规范的一个实现。

    CommonJS对于模块的定义非常简单,分为模块定义(exports),模块引用(require),模块标示三部分。
    通过全局变量 exports 返回当前模块希望提供给其他模块的对象:

     1 // 定义行为
     2 function foobar(){
     3         this.foo = function(){
     4                 console.log('Hello foo');
     5         }
     6 
     7         this.bar = function(){
     8                 console.log('Hello bar');
     9         }
    10 }
    11 // 把 foobar 暴露给其它模块
    12 exports.foobar = foobar;

    通过全局函数 require 来导入其他模块的输出:

    1 //使用文件与模块文件在同一目录
    2 var foobar = require('./foobar').foobar,
    3 test = new foobar();
    4 test.bar(); // 'Hello bar'

    模块标示其实就是传递给require方法的参数,用来指定加载文件路径,可以没有后缀名.js,例如上面例子中的 “./foobar”。

    CommonJS模块的代码都运行在模块作用域,不会污染全局作用域,模块可以多次加载,但是结果会被缓存。CommonJS主要是为服务器端JavaScript运行库设计的,模块是同步加载的,这使得难以在浏览器中运行CommonJS代码。Node.js上面有一些项目例如Browserify,将CommonJS带进了浏览器,Browserify将依赖到的单独的js文件打包成一个单独的js文件,统一加载到浏览器端。
     

    2. AMD

    AMD(异步模块定义)是为浏览器环境设计的,采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

    模块通过 define 函数定义在闭包中,格式如下:

    1 define(id?: String /*可选*/,
    2        dependencies?: String /*可选*/,
    3        factory: Function|Object /*用来初始化模块或对象的函数*/);

    id 是模块的名字,它是可选的参数。dependencies 指定了所要依赖的模块列表,它是一个数组,也是可选的参数,每个依赖的模块的输出将作为参数一次传入 factory 中。factory 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值。

    定义一个名为 myModule 的模块,它依赖 foo, bar 模块:

     1 define('myModule',
     2     // 依赖
     3     ['foo', 'bar'],
     4     // 依赖(foo 和 bar)被映射为函数的参数
     5     function ( foo, bar ) {
     6         // 返回一个定义了模块导出接口的值
     7         // 在这里创建模块
     8         var myModule = {
     9             doSomething:function(){
    10             }
    11         }
    12         return myModule;
    13 });

    定义一个独立模块,不需要依赖任何其他模块:

    define(function () {
        return {
            doSomething: function() {}
        };
    });

    通过 require 调用模块:

    1 require(['foo', 'bar'], function ( foo, bar ) {
    2         foo.doSomething();
    3 });

    在模块定义内部也可以使用require来加载其他模块:

     1 define(function ( require ) {
     2     var isReady = false, foobar;
     3 
     4     require(['foo', 'bar'], function (foo, bar) {
     5         isReady = true;
     6         foobar = foo() + bar();
     7     });
     8 
     9     return {
    10         isReady: isReady,
    11         foobar: foobar
    12     };
    13 });

    上面的例子中 foo 和 bar没有加载完成之前,isReady属性为 false。

    目前主要有两个Javascript库实现了AMD规范:require.js和curl.js。RequireJS由James Burke创建,他也是AMD规范的创始人。

    3. 结语

    CommonJS 则采用了服务器优先的策略,使用同步方式加载模块,而且试图涵盖更多更宽泛的东西,例如文件IO,Promise等等。而AMD 采取了一种浏览器优先的方式来开发,使用异步方式加载模块。它支持对象、函数、构造器、字符串、JSON 以及其它许多类型的模块,运行在浏览器本地环境之中。

    由于当前版本的Javascript没有提供原生的模块化支持,社区的开发者进行了很多模块化的探索,使得Javascript工程化成为了可能,CommonJS和AMD就是最主要的两个规范。

  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/tedzhao/p/Javascript_module_programming.html
Copyright © 2011-2022 走看看