javascript基础修炼——UMD规范的代码推演

UMD规范,就是所有规范里长得最丑的那个,没有之一!!!它是为了让模块同时兼容AMD和CommonJs规范而出现的,多被一些需要同时支持浏览器端和服务端引用的第三方库所使用。UMD是一个 

时代的产物,当各种环境最终实现ES harmony的统一的规范后,它也将退出历史舞

    1、UMD规范
    地址:https://github.com/umdjs/umd

    UMD规范,就是所有规范里长得最丑的那个,没有之一!!!它是为了让模块同时兼容AMD和CommonJs规范而出现的,多被一些需要同时支持浏览器端和服务端引用的第三方库所使用。UMD是一个时代的 
    产物,当各种环境最终实现ES harmony的统一的规范后,它也将退出历史舞台。

    UMD规范的结构乍一看非常复杂,主要是因为想要看懂这段范式需要一些javascript基础知识,它的基本结构是这样的


      (function (root, factory) {   
       if (typeof define === 'function' && define.amd) {        // AMD
         define(['jquery', 'underscore'], factory);
         } else if (typeof exports === 'object') {        // Node, CommonJS之类的
          module.exports = factory(require('jquery'), require('underscore'));
         } else {        // 浏览器全局变量(root 即 window)
        root.returnExports = factory(root.jQuery, root._);
        }
        }(this, function ($, _) {    //    方法
         function a(){};    //    私有方法,因为它没被返回 (见下面)
         function b(){};    //    公共方法,因为被返回了
         function c(){};    //    公共方法,因为被返回了

       //    暴露公共方法
       return {b: b,c: c}
      }));
  1. 源码范式推演
    2.1 基本结构

先来看最外层的结构:

  (function (){}());

非常简单,就是一个自执行函数。既然它是一个模块化的标准,也就意味着这个自执行函数最终可以导出一个模块,那么从代码的角度来讲实际上有两种常见的实现方式:

1, return返回一个模块;
2,实参传入一个对象,把函数内部生成好的需要导出的东西挂在这个对象的属性上;

可以看到上面的函数体内部是没有return语句的,那么可以猜测UMD在实现时是采用了第二种方式。既然UMD是一种模块化的规范,那么它的功能就是根据使用要求生产模块,

也就是说它的职责定位叫做模块工厂,我们可以定义一个factory方法,每当执行该方法时,就回返回一个模块,所以它的基本结构就变成了如下的样子

 (function (factory){    //假设没有使用任何模块化方案,那么将工厂函数执行后返回的内容直接挂载到全局
    window.Some_Attr = factory();
  }(function(){    //自定义模块主体的内容
      var a,b,c
      function a1(){}
      function b1(){}
      function c1(){}
      return {
       a:a1,
       b:b1
      }
   }))

也就是说我们自定义一个匿名函数,然后把它当做实参传给了自执行函数,然后在自执行函数内部通过形参来访问这个工厂方法(或者你会更熟悉回调函数或callback这样的叫法),

把它简单地挂在到全局对象上,这样就完成了基本的模块导出

有的时候我们也希望可以将模块挂载到非全局的环境,将挂载对象动态传入可以让代码变得更灵活,此处涉及到一个基础知识,就是浏览器环境中的全局对象拥有parent,top,self三个属性来追踪

页面中嵌入<iframe>后引入的新的Window对象的,单页面Window.self是指向自己的,代码中常通过是否包含self属性来鉴别全局对象,所以此处的写法可以改进为兼容:

  (function(root,factory){
     root.Some_Attr = factory();
  }(self !== undefined ? self : this, function(){

 }));

2.2 适配AMD

接着我们先来加入AMD的规范的适配,规范地址:AMD规范github地址

   /*
    * AMD规范的模块定义格式是define(id?, dependencies?, factory),factory就是实际的模块内容
    */(function (factory){    //判断全局环境是否支持AMD标准
       if(typeof define === 'function' && define.amd){        //定义一个AMD模块
        define([/*denpendencies*/],factory);
      } 
      }(function(/*formal parameters*/){    //自定义模块主体的内容
   /*
      var a,b,c
      function a1(){}
      function b1(){}
      function c1(){}
      return {
        a:a1,
        b:b1
      }
   */}))
posted @ 2021-04-27 13:50  蔺雨轩  阅读(664)  评论(0)    收藏  举报