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.pswp.cn/news/282331.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282331.shtml
英文地址,請注明出處:http://en.pswp.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…

bzoj1143/2718 祭祀river(最大獨立集)

[CTSC2008]祭祀river Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2175 Solved: 1098[Submit][Status][Discuss]Description 在遙遠的東方,有一個神秘的民族,自稱Y族。他們世代居住在水面上,奉龍王為神。每逢重大慶典, Y族…

反向ajax實現

在過去的幾年中,web開發已經發生了很大的變化。現如今,我們期望的是能夠通過web快速、動態地訪問應用。在這一新的文章系列中,我們學習如何使用反 向Ajax(Reverse Ajax)技術來開發事件驅動的web應用,以此來…

linux系統啟動流程及常見問題的解決

一、前言計算機開機是一個神秘的過程。我們只是按了開機鍵,就看到屏幕上的進度條或者一行行的輸出,直到我們到達登錄界面。然而,計算機開機又是個異常脆弱的過程,我們滿心期望的登錄界面可能并不會出現,而是一個命令行…

使用.NET開發一個屏幕OCR工具

本文將介紹使用.NET開發的一款桌面截圖 OCR 工具,軟件已開源,地址:https://github.com/sangyuxiaowu/Snipping_OCR背景因為不同地方人們的使用習慣不同,國內可能截圖更多的是使用QQ,微信等即時聊天工具提供的截圖功能。…

segnet 編譯與測試

segnet 編譯與測試參考:http://sunxg13.github.io/2015/09/10/caffe/http://m.blog.csdn.net/lemianli/article/details/76687508http://blog.h5min.cn/u010069760/article/details/75258539(注意:nakefile而非makefile.config)1、…

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…

TemplateBinding與Binding區別,以及WPF自定義控件開發的遭遇

在上一次的文章WPF OnApplyTemplate 不執行 或者執行滯后的疑惑談到怎么正確的開發自定義控件&#xff0c;我們控件的樣式中&#xff0c;屬性的綁定一般都是用TemplateBinding來完成,如下一個基本的按鈕樣式&#xff1a; <Style x:Key"SimpleButton" TargetType&q…

Layui版本的WPF開源控件庫-Layui-WPF

大家好&#xff0c;我是沙漠盡頭的狼。今天介紹一款Layui風格的WPF開源控件庫&#xff0c;倉庫信息如下&#xff1a;倉庫地址&#xff1a;https://github.com/Layui-WPF-Team/Layui-WPF倉庫截圖&#xff1a;Layui-WPF關于Layui請點擊此鏈接[1]了解&#xff0c;本文不做介紹&…

Mycat 之 通過Keepalived 實現高可用

一、系統拓撲圖 一、操作方法 參考本博客的Nginx Keepalived 實現高可用轉載于:https://blog.51cto.com/12965094/2164485

Nginx使用upstream實現動靜分離

一、為什么要進行動靜分離 分離資源&#xff0c;減少不必要到的請求消耗&#xff0c;減少請求延時。 注&#xff1a;我這里&#xff0c;是nginx處理靜態資源&#xff0c;apache處理動態資源。 場景分析&#xff1a; 1、未分離之前的場景步驟 &#xff08;1&#xff09;客戶…

HMAC

HMAC 的用途 HMAC 算法主要應用于身份驗證&#xff0c;用法如下&#xff1a; 1.客戶端發出登錄請求2.服務器返回一個隨機值&#xff0c;在會話記錄中保存這個隨機值3.客戶端將該隨機值作為密鑰&#xff0c;用戶密碼進行 hmac 運算&#xff0c;遞交給服務器4.服務器讀取數據庫中…

JS的原型鏈和繼承

原型和原型鏈 原型prototype&#xff0c;在創建新函數的時候&#xff0c;會自動生成&#xff0c;而prototype中也會有一個constructor&#xff0c;回指創建該prototype的函數對象。 __proto__是對象或者實例中內置的[[prototype]]&#xff0c;其指向的是產生該對象的對象的prot…

Android 的滑動分析以及各種實現

一、滑動效果的產生滑動一個View&#xff0c;本質區別就是移動一個View。改變當前View所在的坐標&#xff0c;原理和動畫相似不斷改變坐標位置實現。實現View的滑動就必須監聽滑動的事件&#xff0c;并且根據事件傳入的坐標&#xff0c;動態且不斷改變View的坐標&#xff0c;從…

微軟產品 .NET 6 遷移之旅

“.NET性能不行&#xff01;”“.NET有什么像樣的產品嗎&#xff01;&#xff1f;”“升級到.NET 6有什么好處&#xff01;&#xff1f;”……聽人扯淡還不如看看微軟自己是怎么做的。本文將匯總一下微軟的開發博客——這些博客均涉及微軟將產品和服務遷移到.NET 6的成果。博客…

Navicat 連接 RDS數據庫

場景介紹&#xff1a; 隨著業務量的逐漸增加&#xff0c;公司的數據庫壓力也會逐漸增大&#xff0c;使用自己購買的esc創建的mysql的話&#xff0c;還得考慮相應的dba維護&#xff0c;也比較繁瑣&#xff0c;說不定還做的并不完美&#xff0c;這時&#xff0c;RDS就派上用場了&…

bzoj1045 糖果傳遞

Description 有n個小朋友坐成一圈&#xff0c;每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個糖果代價為1。 Input 第一行一個正整數nn<1000000&#xff0c;表示小朋友的個數&#xff0e;接下來n行&#xff0c;每行一個整數ai&#xff0c;表示第i個小朋友得…

BEGINNING SHAREPOINT#174; 2013 DEVELOPMENT 第9章節--client對象模型和REST APIs概覽 client對象模型API范圍...

BEGINNING SHAREPOINT 2013 DEVELOPMENT 第9章節--client對象模型和REST APIs概覽 client對象模型API范圍 本章之前提到過。client對象模型應用中一個不足就是缺乏對SP APIs和訪問功能的支持不足。轉載于:https://www.cnblogs.com/yutingliuyl/p/6748382.html

為.NET應用添加截圖功能

本文介紹了 .NET 實現截圖功能的思路和過程&#xff0c;如果你僅想了解最后的解決方案&#xff0c;可以直接查看文章末尾。截圖的功能我們應該都經常使用&#xff0c;在開發軟件時&#xff0c;我們有時也或多或少需要提供這方面的功能&#xff0c;無論是為用戶更方便提供遠程診…