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

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

1. UMD规范

地址:https://github.com/umdjs/umd

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

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

(function (root, factory) {if (typeof define === 'function' && define.amd) {// AMDdefine(['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}
}));

2. 源码范式推演

2.1 基本结构

先来看最外层的结构:

(function (){}());

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

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

可以看到上面的函数体内部是没有return语句的,那么可以猜测UMD在实现时是采用了第二种方式。既然UMD是一种模块化的规范,那么它的功能就是根据使用要求生产模块,也就是说它的职责定位叫做模块工厂,我们可以定义一个factory方法,每当执行该方法时,就回返回一个模块,所以它的基本结构就变成了如下的样子:

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

2.3 适配CommonJs

接着我们先来加入CommonJs的规范的适配:

/*
* CommonJs规范使用require('moduleName')的格式来引用模块,使用module.exports对象输出模块,所以只要把模块的输出内容挂载到module.exports上就完成了模块定义。
*/
(function (factory){//判断全局环境是否支持CommonJs标准if(typeof exports === 'object' && typeof define !== 'function'){module.exports = factory(/*require(moduleA), require(moduleB)*/);}
}(function(/*formal parameters*/){//自定义模块主体的内容/*var a,b,cfunction a1(){}function b1(){}function c1(){}return {a:a1,b:b1}*/
}))

加入对CommonJs的适配后,函数主体中return的内容(一般是一个对象)就被挂载到了module.exports上,如果你编写过node.js代码,对此一定不会陌生。

把上面的片段揉到一块,你也就看懂UMD的样子了。

3. 更具针对性的UMD范式

UMD在其github主页上提供了更具针对性的范式,适用于不同的场景,感兴趣的读者可以自行查看(地址在第一节已经给出)。

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

在此贴一个可能对大多数开发者比较有用的jqueryPlugin的开发范式,如果看懂了上面的分析,那么下面的代码应该不难看懂:

// Uses CommonJS, AMD or browser globals to create a jQuery plugin.
(function (factory) {if (typeof define === 'function' && define.amd) {// AMD. Register as an anonymous module.define(['jquery'], factory);} else if (typeof module === 'object' && module.exports) {// Node/CommonJSmodule.exports = function( root, jQuery ) {if ( jQuery === undefined ) {// require('jQuery') returns a factory that requires window to// build a jQuery instance, we normalize how we use modules// that require this pattern but the window provided is a noop// if it's defined (how jquery works)if ( typeof window !== 'undefined' ) {jQuery = require('jquery');}else {jQuery = require('jquery')(root);}}factory(jQuery);return jQuery;};} else {// Browser globalsfactory(jQuery);}
}(function ($) {$.fn.jqueryPlugin = function () { return true; };
}));

4. 模块化开发

前端模块化本身是一个稍显混乱的话题,笔者自己最初也是require( )require.js傻傻分不清楚,但模块化是前端开发中非常重要的课题,如果你不想一辈子只是在一个页面内写代码,这一关是一定要过的,感兴趣的读者可以按照下面的基本类别划分分块进行学习。

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

转载于:https://blog.51cto.com/13869008/2163409

javascript基础修炼(4)——UMD规范的代码推演相关推荐

  1. javascript基础修炼(11)——DOM-DIFF的实现

    参考代码将上传至我的github仓库,欢迎互粉:https://github.com/dashnowords/blogs/tree/master 一. 再谈从Virtual-Dom生成真实DOM 在上 ...

  2. javascript基础修炼(10)——VirtualDOM和基本DFS

    本篇只是部分原理的学习笔记,并不代表框架真实源码的实现逻辑. 1. Virtual-DOM是什么 Virtual-DOM,即虚拟DOM树.浏览器在解析文件时,会将html文档转换为document对象 ...

  3. JavaScript基础修炼(14)——WebRTC在浏览器中如何获得指定格式的PCM数据【华为云分享】

    [摘要] WebRTC音频处理基础知识及实战 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 本 ...

  4. javascript基础修炼(1)——一道十面埋伏的原型链面试题

    在基础面前,一切技巧都是浮云. 题目是这样的 要求写出控制台的输出 题目涉及的知识点 1.this的指向 2.原型机原型链 3.类的继承 4.原始类型和引用类型的区别 5.每一个知识点都可以拿出来做单 ...

  5. javascript基础修炼——手把手教你造一个简易的require.js

    require.js造轮子 示例代码托管在我的代码仓:http://www.github.com/dashnowords/blogs 一. 概述 许多前端工程师沉浸在使用脚手架工具的快感中,认为req ...

  6. JavaScript基础修炼(14)——WebRTC在浏览器中如何获得指定格式的PCM数据

    我的github主页:https://github.com/dashnowords 我的新书上架啦,3天即登京东计算机编程语言类排行榜Top1!!!精选30+JavaScript库,从使用方式,设计原 ...

  7. JavaScript基础第05天【笔记+代码】

    函数.作用域.预解析.对象 昨日复习 01 - arguments使用 5. arguments的使用 02 - 利用函数求任意个数的最大值 03 - 利用函数翻转数组 04 - 利用函数冒泡排序 0 ...

  8. javascript基础修炼(13)——记一道有趣的JS脑洞练习题

    [摘要] 开脑洞,也巩固基础知识 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 一. 题目 改 ...

  9. javascript基础修炼——前端路由的基本原理

    前端路由,顾名思义就是一个前端不同页面的状态管理器,可以不向后台发送请求而直接通过前端技术实现多个页面的效果. [造轮子]是笔者学习和理解一些较复杂的代码结构时的常用方法,它很慢,但是效果却胜过你读十 ...

最新文章

  1. 局域网瘫痪 傀儡主机的DDoS***
  2. 截屏工具Snipaste使用指南
  3. 用UltraEdit判断打开文件的编码类型 用UltraEdit或notepad记事本查看文件编码格式 用UltraEdit查看当前文件编码...
  4. SQL查询【根据生日计算】
  5. 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题
  6. 计算机操作系统(3):操作系统的基本特征
  7. ZDB5304烧写方法
  8. 告别刷抖音!30秒一个Python小例子,总有一款适合你,赶紧收藏!
  9. clion变量配置_cygwin安装和clion配置
  10. redis哨兵配置和redis-cluster搭建
  11. 两个可用于浏览器兼容性测试的Firefox插件
  12. 算法设计与分析——算法分析基础
  13. winForm中 Invalidate(),Update(),Reflash(),
  14. MacBook在任意文件夹目录打开终端
  15. matlab画黎曼函数,[2018年最新整理]matlab画复数函数图象和黎曼面.docx
  16. 关于CNN中感受野的理解和计算方法
  17. 2019最应该投资什么?是你明年的北大核心
  18. quartus 使用技巧
  19. 华中科技大学计算机组成,华中科技大学计算机组成原理.pptx
  20. A - Portal(cf) 前缀和 区间维护

热门文章

  1. b样条和三次样条_样条曲线
  2. IllegalArgumentException:argument type mismatch
  3. flex如何做响应式设计_响应式设计-您做错了!
  4. 聊聊storm的PartialKeyGrouping
  5. hdfoo站点开发笔记
  6. cocos2d-js 热更新具体解释(一)
  7. gtk+学习笔记(五)
  8. 图片处理--熔铸特效
  9. [导入]C++程序随笔
  10. PHP 发送Email的几种方法