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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Missing artifact log4j:log4j:bundle:1.2.17

为什么80%的码农都做不了架构师?>>> maven引入log4jjar包出现Missing artifact log4j:log4j:bundle:1.2.17,解决方法是去掉bundle,其他的解决方案可以参考maven log4j.jar问题 Maven使用log4j可能会有协议上的问题 如果log4j的版…

PHPStorm 配置远程服务器文件夹在本地windows镜像,实现代码自动同步(类似于Samba架构文件同步功能)

场景介绍: 这是一种类似samba架构,也和 filezillaxshell 模式相类似的代码文件同步的模式,但是却更加优雅,也更加方便简洁。环境介绍: 本地windows端:编辑器phpstorm 远程Linux端:centos&#x…

反向ajax实现

在过去的几年中,web开发已经发生了很大的变化。现如今,我们期望的是能够通过web快速、动态地访问应用。在这一新的文章系列中,我们学习如何使用反 向Ajax(Reverse Ajax)技术来开发事件驱动的web应用,以此来…

linux系统启动流程及常见问题的解决

一、前言计算机开机是一个神秘的过程。我们只是按了开机键,就看到屏幕上的进度条或者一行行的输出,直到我们到达登录界面。然而,计算机开机又是个异常脆弱的过程,我们满心期望的登录界面可能并不会出现,而是一个命令行…

使用.NET开发一个屏幕OCR工具

本文将介绍使用.NET开发的一款桌面截图 OCR 工具,软件已开源,地址:https://github.com/sangyuxiaowu/Snipping_OCR背景因为不同地方人们的使用习惯不同,国内可能截图更多的是使用QQ,微信等即时聊天工具提供的截图功能。…

Linux开启fileinfo扩展

在项目初始部署环境的时候,可能考虑的并不全面,就会少装一些扩展,这里讲解如何添加fileinfo扩展1、找到php安装的压缩包2、将压缩包cp到 /data目录下,并解压 cp php-7.0.30.tar.gz /data cd /data tar -zxvf php-7.0.30.tar.gz…

Layui版本的WPF开源控件库-Layui-WPF

大家好,我是沙漠尽头的狼。今天介绍一款Layui风格的WPF开源控件库,仓库信息如下:仓库地址:https://github.com/Layui-WPF-Team/Layui-WPF仓库截图:Layui-WPF关于Layui请点击此链接[1]了解,本文不做介绍&…

Mycat 之 通过Keepalived 实现高可用

一、系统拓扑图 一、操作方法 参考本博客的Nginx Keepalived 实现高可用转载于:https://blog.51cto.com/12965094/2164485

微软产品 .NET 6 迁移之旅

“.NET性能不行!”“.NET有什么像样的产品吗!?”“升级到.NET 6有什么好处!?”……听人扯淡还不如看看微软自己是怎么做的。本文将汇总一下微软的开发博客——这些博客均涉及微软将产品和服务迁移到.NET 6的成果。博客…

Navicat 连接 RDS数据库

场景介绍: 随着业务量的逐渐增加,公司的数据库压力也会逐渐增大,使用自己购买的esc创建的mysql的话,还得考虑相应的dba维护,也比较繁琐,说不定还做的并不完美,这时,RDS就派上用场了&…

为.NET应用添加截图功能

本文介绍了 .NET 实现截图功能的思路和过程,如果你仅想了解最后的解决方案,可以直接查看文章末尾。截图的功能我们应该都经常使用,在开发软件时,我们有时也或多或少需要提供这方面的功能,无论是为用户更方便提供远程诊…

K8S集群Master高可用实践

本文将在前文基础上介绍k8s集群的高可用实践,一般来讲,k8s集群高可用主要包含以下几个内容:1、etcd集群高可用2、集群dns服务高可用3、kube-apiserver、kube-controller-manager、kube-scheduler等master组件的高可用 其中etcd实现的办法较为…

[转载]智能科普:VR、AR、MR的区别

智能科普:VR、AR、MR的区别 http://news.zol.com.cn/553/5534833.html news.zol.com.cn 2015-11-23 16:00近日, 获得谷歌5亿美元融资的技术公司Magic Leap在WSJD展会中放出了一段实录视频,引起不小骚动。如今,也有媒体称他们为MR公…

PHP项目中,记录错误日志

一、场景介绍: 环境:LNMP 我们通常是通过nginx的错误日志来分析分错的,也就是我们在各个server中定义的error_log。 比如下面这样,就是将错误日志定义在/etc/nginx/logs/error/www.xiaobudiu.top.log,发生错误&#xf…

持续集成指南:GitLab 的 CI/CD 工具配置与使用

1前言写代码这项工作,本质就是将工作自动化,减少手工操作提供效率,因为人的本质都是懒狗,程序员也不能例外,为了各种意义的效率提升(懒),我们需要持续集成工具,将代码测试…

php 错误日志 redis' already loaded in Unknown on line 0

环境介绍:LNMP 报错信息:注:这个php_errors.log 是我在php.ini 中定义的错误日志路径 问题原因: 报错信息给出的意思是:redis和memcache 模块已经加载过问题解决: php加载模块有两种方式,一种是…

第一周作业

我的Git账号:AI1452349541 和代码图 这是我在电脑和手机上下的网易有道词典 , C也下了。 ***学习内容总结*** 感觉任务并不是很难,有些任务没完成是 因为还没买电脑不好弄,下周电脑一定到位。 ***遇到的问题…

升级MariaDB为10.1版本

2019独角兽企业重金招聘Python工程师标准>>> CentOS中升级mariadb为10.1GA版本。 1、如果有,停止服务 systemctl stop mariadb 2、卸载原来的数据库服务 yum -y remove mari* 3、删除数据库文件 rm -rf /var/lib/mysql/* 4.创建/etc/yum.repos.d/MariaDB…

第一篇文章

第一次写博客。欢迎各位大牛捧场转载于:https://www.cnblogs.com/clnchanpin/p/6753665.html

羊了个羊的Ignite大会又来啦

据说最近羊了个羊非常火啊~可惜没有时间精力研究。不过,薅微软羊毛的机会我是一定不会错过的,这不,薅羊毛的机会来了,哈哈哈。作为经常薅微软羊毛的老司机,今天收到了微软的邮件,告知有新的羊毛…