摘要:廢話真多,是的哈而要說清和的二三事,又不是件容易的事,簡單理解,和指向同一內存區域。而對于當前模塊來說是外部的模塊。參考關于和的區別和的區別這篇文章很不賴。
AMD中define常見的形式
define("alpha" ,["require", "exports", "module"], function(require, exports, module) { var foo = require("foo"); module.exports = exports = function() { foo.doSomething(); } });
參數
第一個是要定義的模塊名字(id)
第二個是要用到的模塊名,其實更專業點講是定義的這個模塊所依賴的模塊名稱
第三個回調函數,是要定義模塊內容
分析方法:替換部分代碼進行分析
先來把回調中的require,exports,module替換了看看。
1.替換requirefunction callback(exports, module) { // 假設foo是最簡單的對象,把require("foo")換成最簡答的對象看看 var foo = { "doSomething": function() {} }; module.exports = exports = function() { foo.doSomething(); } }
那么其實已經不難看出,require其實就相當于是個查詢函數吧,我給他傳個對象名,它就能給我一個具體的對象。
var require = function(name) { var modules = {"foo": {"doSomething": function() {}}}; return modules[name] || {}; }
那么整個代碼可以換成
var require = function(name) { var modules = {"foo": {"doSomething": function() {}}}; return modules[name] || {}; } function callback(exports, module) { var foo = require("foo"); module.exports = exports = function() { foo.doSomething(); } }
看起來好像有點道理哦,等會兒,等會兒,這里的modules又從哪兒冒出來的,哈哈哈,被發現了,別急慢慢來
2. 替換exports和module.exports在替換之前,先來了解下exports和module.exports這兩貨是干啥的,而要了解他們先來看看模塊是啥。
其實模塊么,簡單來說就是一個高級別的function,輸入,處理,輸出。至于為啥js的模塊化為啥這么困難,這個問題不是三言兩語就能解釋清楚的,就不展開了(其實真實情況是,我也不清楚,哈哈哈)
既然模塊要做輸出,那么輸出什么東西總要知道吧,而module.exports的作用就是這個,存儲模塊輸出的內容。
也就是說,這個模塊中要給外部使用的東西全放在module.exports里頭了。廢話真多,是的哈- -.
而要說清exports和module.exports的二三事,又不是件容易的事,簡單理解,exports和module.exports指向同一內存區域。有興趣可以看看exports 和 module.exports 的區別。
那來改造一下,把module.exports,exports也提煉出來看看
var require = function(name) { var modules = {"foo": {"doSomething": function() {}}}; return modules[name] || {}; } var module = {}; var module.exports = exports = {}; function callback() { var foo = require("foo"); module.exports = exports = function() { foo.doSomething(); } }define的推測
// 這里的id相當于模塊名,deps就是需要依賴的模塊名稱列表 define = function(id , deps, callback) { callback(require, exports, module); };
暈,那require,exports,module跑哪兒溜達去了?加上去看看
define = function(id , deps, callback) { var require = function(name) { var modules = {"foo": {"doSomething": function() {}}}; return modules[name] || {}; } var module = {}; var module.exports = exports = {}; callback(require, exports, module); };
看上去挺有道理的么,那么modules這玩意兒到底是哪兒冒出來的呢。
可以看出來modules 里面存放著的是foo模塊的內容,那這些內容是怎么來的呢?通過foo的module.exports提供的啊。那么modules里面其實放的是,foo的module.exports。
而foo對于當前模塊來說是外部的模塊。而我想調用外面的東西,只有兩種辦法,要么傳參數,要么通過全局變量(不過或許大神還有其他方案,我就只曉得這兩種了)。define里面有的參數沒有一個是存放module.exports的。那么答案呼之欲出了,modules是全局變量。
modules = {}; function load(id, exports) { (modules || (modules = {}))[id] = exports; }
再來看看完整的代碼,變成啥樣了
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { var require = function(name) { return modules[name] || {}; } var module = {}; var module.exports = exports = {}; callback(require, exports, module); load(id, module.exports); };
到現在差不多已經成型了,那么這里的require, exports, module都是外來的模塊吧bingo,其實callback里的模塊都是根據deps來的,去掉require, exports, module
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { // 相當于 // var module = {}; // var module.exports = {}; var module = modules["module"]; // 相當于 //var require = function(name) { // return modules[name] || {}; //} var require = modules["require"]; var args = deps.map(require); callback.apply(null, args); load(id, module.exports); };來看define的另一種形式
define("alpha" ,["foo"], function(foo) { return function() { foo.doSomething(); } });
咦,精簡了不少誒。沒有exports了誒,會返回了么
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { var module = modules["module"]; var require = modules["require"]; var args = deps.map(require); var exports = callback.apply(null, args); load(id, exports || module.exports); };
OK,先告一段落了,累死我丫了。在慢慢優化吧,唉。
參考(關于exports 和 module.exports 的區別)exports 和 module.exports 的區別這篇文章很不賴。
人家大神已經說得非常好了。我在了淺薄的打個比方,我有個文件夾叫module.exports,然后我創建了一個超鏈接叫exports,那我在任何一個里面操作最終都會反應到另一個里,但如果我把超鏈接exports刪了把它的指向地址改了,并不會影響真正的文件夾module.exports。
而有很多人明明已經改了超鏈接exports的指向地址(如:exports = 123;),再在超鏈接里面做了很多操作(如:exports.hello = 456;),那都不會對真正的文件夾module.exports起到任何作用(你是見不到module.exports.hello === 456的)。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79529.html
摘要:前言由于博主最近又閑下來了,之前覺得的官方文檔比較難啃一直放到現在。文章會逐步分析每個處理的用意當然是博主自己的理解,不足之處歡迎指出溝通交流。后續將會補上構建生產的配置分析,案例參考。前端臨床手札構建逐步解構下 前言 由于博主最近又閑下來了,之前覺得webpack的官方文檔比較難啃一直放到現在。細心閱讀多個webpack配置案例后覺得還是得自己寫個手腳架,當然這個案例是基于vue的,...
摘要:一冒泡和捕獲事件執行子元素在執行某個事件的前后,會引起上層元素觸發相同事件。三補充關于和這兩個其實和捕獲與冒泡一點關系都沒有,是用來阻止事件的默認行為的。 一、冒泡和捕獲 事件執行:子元素在執行某個事件的前后,會引起上層元素觸發相同事件。例:我點擊了div,那么不光div會執行click事件,上層的body和html等等也會執行click。 冒泡與捕獲解決了:事件執行順序由誰開始,由誰...
摘要:感覺不能這樣下去就學寫一下單元測試,等他更新代碼我都跑一遍確認一下,這樣工作安心多了。具體執行的測試用例實現代碼。測試工具斷言庫測試驅動開發及測試框架入門學習 最近博主工作是和另一枚后端合作,但是經常發現他寫的接口出錯,苦逼連連。感覺不能這樣下去就學寫一下單元測試,等他更新代碼我都跑一遍確認一下,這樣工作安心多了。 經過博主一番查找,貌似被推薦比較多的有mocha和chai,下面記錄簡...
摘要:感覺不能這樣下去就學寫一下單元測試,等他更新代碼我都跑一遍確認一下,這樣工作安心多了。具體執行的測試用例實現代碼。測試工具斷言庫測試驅動開發及測試框架入門學習 最近博主工作是和另一枚后端合作,但是經常發現他寫的接口出錯,苦逼連連。感覺不能這樣下去就學寫一下單元測試,等他更新代碼我都跑一遍確認一下,這樣工作安心多了。 經過博主一番查找,貌似被推薦比較多的有mocha和chai,下面記錄簡...
摘要:然而我真的太天真,微信瀏覽器怎樣會讓你這樣好過問題集中于自動播放視頻這塊,需求很簡單自動播放全屏不顯示工具條自動播放一步步來,自動播放這個問題在十分肯定默認是不支持的,必須基于用戶操作下才能加載視頻。至于在微信下和一個樣。 某天收到舊同事的信息說希望我幫手做一下一個簡單的H5,然后我看了看的確很簡單: 就是圖片滾動到最后自動播放視頻,播完顯示個按鈕交互。 然而我真的太天真,微信瀏覽器怎...
閱讀 1737·2021-10-18 13:30
閱讀 2614·2021-10-09 10:02
閱讀 2968·2021-09-28 09:35
閱讀 2094·2019-08-26 13:39
閱讀 3525·2019-08-26 13:36
閱讀 1954·2019-08-26 11:46
閱讀 1138·2019-08-23 14:56
閱讀 1699·2019-08-23 10:38