国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【JS基礎(chǔ)】一文看懂前端模塊化規(guī)范

HelKyle / 1590人閱讀

摘要:參考資料前端模塊化詳解完整版入門近一萬字的語法知識(shí)點(diǎn)補(bǔ)充徹底搞清楚中的和和詳解

前言

前端的模塊化之路經(jīng)歷了漫長的過程,想詳細(xì)了解的小伙伴可以看浪里行舟大神寫的前端模塊化詳解(完整版),這里根據(jù)幾位大佬們寫的文章,將模塊化規(guī)范部分做了匯總和整理,希望讀完的小伙伴能有些收獲,也希望覺得有用的小伙伴可以點(diǎn)個(gè)贊,筆芯。

什么是模塊

將一個(gè)復(fù)雜的程序依據(jù)一定的規(guī)則(規(guī)范)封裝成幾個(gè)塊(文件), 并進(jìn)行組合在一起

塊的內(nèi)部數(shù)據(jù)與實(shí)現(xiàn)是私有的,只是向外部暴露一些接口(方法)與外部其它模塊通信

CommonJS

Node 應(yīng)用由模塊組成,采用 CommonJS 模塊規(guī)范。每個(gè)文件就是一個(gè)模塊,有自己的作用域。在一個(gè)文件里面定義的變量、函數(shù)、類,都是私有的,對(duì)其他文件不可見。在服務(wù)器端,模塊的加載是運(yùn)行時(shí)同步加載的;在瀏覽器端,模塊需要提前編譯打包處理。

CommonJS規(guī)范加載模塊是同步的,也就是說,只有加載完成,才能執(zhí)行后面的操作。

基本語法:

暴露模塊:module.exports = valueexports.xxx = value

引入模塊:require(xxx),如果是第三方模塊,xxx為模塊名;如果是自定義模塊,xxx為模塊文件路徑

但是,CommonJs有一個(gè)重大的局限使得它不適用于瀏覽器環(huán)境,那就是require操作是同步的。這對(duì)服務(wù)器端不是一個(gè)問題,因?yàn)樗械哪K都存放在本地硬盤,可以同步加載完成,等待時(shí)間就是硬盤的讀取時(shí)間。但是,對(duì)于瀏覽器,這卻是一個(gè)大問題,因?yàn)槟K都放在服務(wù)器端,等待時(shí)間取決于網(wǎng)速的快慢,可能要等很長時(shí)間,瀏覽器處于”假死”狀態(tài)。

因此,瀏覽器端的模塊,不能采用”同步加載”(synchronous),只能采用”異步加載”(asynchronous),這就是AMD規(guī)范誕生的背景。

AMD

特點(diǎn):非同步加載模塊,允許指定回調(diào)函數(shù),瀏覽器端一般采用AMD規(guī)范

代表作:require.js

用法:

//定義沒有依賴的模塊
define(function(){
   return 模塊
})

//定義有依賴的模塊
define(["module1", "module2"], function(m1, m2){
   return 模塊
})

//引入使用模塊
require(["module1", "module2"], function(m1, m2){
   //使用m1/m2
})
CMD

特點(diǎn):專門用于瀏覽器端,模塊的加載是異步的,模塊使用時(shí)才會(huì)加載執(zhí)行

代表作:Sea.js

用法:

//定義沒有依賴的模塊
define(function(require, exports, module){
  exports.xxx = value
  module.exports = value
})

//定義有依賴的模塊
define(function(require, exports, module){
  //引入依賴模塊(同步)
  var module2 = require("./module2")
    //引入依賴模塊(異步)
    require.async("./module3", function (m3) {
    })
  //暴露模塊
  exports.xxx = value
})

//引入使用模塊
define(function (require) {
  var m1 = require("./module1")
  var m4 = require("./module4")
  m1.show()
  m4.show()
})
CMD與AMD區(qū)別

AMD和CMD最大的區(qū)別是對(duì)依賴模塊的執(zhí)行時(shí)機(jī)處理不同,而不是加載的時(shí)機(jī)或者方式不同,二者皆為異步加載模塊。

AMD依賴前置,js可以方便知道依賴模塊是誰,立即加載;

而CMD就近依賴,需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K,這也是很多人詬病CMD的一點(diǎn),犧牲性能來帶來開發(fā)的便利性,實(shí)際上解析模塊用的時(shí)間短到可以忽略。

一句話總結(jié):
兩者都是異步加載,只是執(zhí)行時(shí)機(jī)不一樣。AMD是依賴前置,提前執(zhí)行,CMD是依賴就近,延遲執(zhí)行。

UMD

UMD是AMD和CommonJS的糅合:

AMD模塊以瀏覽器第一的原則發(fā)展,異步加載模塊。

CommonJS模塊以服務(wù)器第一原則發(fā)展,選擇同步加載,它的模塊無需包裝(unwrapped modules)。

這迫使人們又想出另一個(gè)更通用的模式UMD (Universal Module Definition)。希望解決跨平臺(tái)的解決方案。

UMD先判斷是否支持Node.js的模塊(exports)是否存在,存在則使用Node.js模塊模式。

在判斷是否支持AMD(define是否存在),存在則使用AMD方式加載模塊。

(function (window, factory) {
    if (typeof exports === "object") {
     
        module.exports = factory();
    } else if (typeof define === "function" && define.amd) {
     
        define(factory);
    } else {
     
        window.eventUtil = factory();
    }
})(this, function () {
    //module ...
});
ES6模塊化

ES6 模塊的設(shè)計(jì)思想是盡量的靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運(yùn)行時(shí)確定這些東西。比如,CommonJS 模塊就是對(duì)象,輸入時(shí)必須查找對(duì)象屬性。

ES6 Module默認(rèn)目前還沒有被瀏覽器支持,需要使用babel,在日常寫demo的時(shí)候經(jīng)常會(huì)顯示這個(gè)錯(cuò)誤:

ES6模塊使用import關(guān)鍵字導(dǎo)入模塊,export關(guān)鍵字導(dǎo)出模塊:

/** 導(dǎo)出模塊的方式 **/

var a = 0;
export { a }; //第一種
   
export const b = 1; //第二種 
  
let c = 2;
export default { c }//第三種 

let d = 2;
export default { d as e }//第四種,別名

/** 導(dǎo)入模塊的方式 **/

import { a } from "./a.js" //針對(duì)export導(dǎo)出方式,.js后綴可省略

import main from "./c" //針對(duì)export default導(dǎo)出方式,使用時(shí)用 main.c

import "lodash" //僅僅執(zhí)行l(wèi)odash模塊,但是不輸入任何值
命名式導(dǎo)出與默認(rèn)導(dǎo)出

export {<變量>}這種方式一般稱為 命名式導(dǎo)出 或者 具名導(dǎo)出,導(dǎo)出的是一個(gè)變量的引用
export default這種方式稱為 默認(rèn)導(dǎo)出 或者 匿名導(dǎo)出,導(dǎo)出的是一個(gè)

舉例:

// a.js
let x = 10
let y = 20
setTimeout(()=>{
    x = 100
    y = 200
},100)
export { x }
export default y

// b.js
import { x } from "./a.js"
import y from "./a.js"
setTimeout(()=>{
    console.log(x,y) // 100,20
},100)
ES6 模塊與 CommonJS 模塊的差異

① CommonJS 模塊輸出的是一個(gè)值的拷貝,ES6 模塊輸出的是值的引用。

CommonJS 模塊輸出的是值的拷貝,也就是說,一旦輸出一個(gè)值,模塊內(nèi)部的變化就影響不到這個(gè)值。而且,CommonJS 模塊無論加載多少次,都只會(huì)在第一次加載時(shí)運(yùn)行一次,以后再加載,返回的都是第一次運(yùn)行結(jié)果的緩存,除非手動(dòng)清除系統(tǒng)緩存。

?ES6 模塊的運(yùn)行機(jī)制與 CommonJS 不一樣,JS 引擎對(duì)腳本靜態(tài)分析的時(shí)候,遇到模塊加載命令import,就會(huì)生成一個(gè)只讀引用,等到腳本真正執(zhí)行時(shí),再根據(jù)這個(gè)只讀引用,到被加載的那個(gè)模塊里面去取值。換句話說,ES6 的import有點(diǎn)像 Unix 系統(tǒng)的“符號(hào)連接”,原始值變了,import加載的值也會(huì)跟著變。因此,ES6 模塊是動(dòng)態(tài)引用,并且不會(huì)緩存值,模塊里面的變量綁定其所在的模塊。

② CommonJS 模塊是運(yùn)行時(shí)加載,ES6 模塊是編譯時(shí)輸出接口。

CommonJS 加載的是一個(gè)對(duì)象(即module.exports屬性),該對(duì)象只有在腳本運(yùn)行完才會(huì)生成。即在輸入時(shí)是先加載整個(gè)模塊,生成一個(gè)對(duì)象,然后再從這個(gè)對(duì)象上面讀取方法,這種加載稱為“運(yùn)行時(shí)加載”。

例如:

// CommonJS模塊
let { stat, exists, readFile } = require("fs");

// 等同于
let _fs = require("fs");
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

上面代碼的實(shí)質(zhì)是整體加載fs模塊(即加載fs的所有方法),生成一個(gè)對(duì)象(_fs),然后再從這個(gè)對(duì)象上面讀取 3 個(gè)方法。因?yàn)橹挥羞\(yùn)行時(shí)才能得到這個(gè)對(duì)象,導(dǎo)致完全沒辦法在編譯時(shí)做“靜態(tài)優(yōu)化”。

ES6 模塊不是對(duì)象,它的對(duì)外接口只是一種靜態(tài)定義,在代碼靜態(tài)解析階段就會(huì)生成。通過export命令顯式指定輸出的代碼,import時(shí)采用靜態(tài)命令的形式。即在import時(shí)可以指定加載某個(gè)輸出值,而不是加載整個(gè)模塊,這種加載稱為“編譯時(shí)加載”或者“靜態(tài)加載”。

// ES6模塊
import { stat, exists, readFile } from "fs";

上面代碼的實(shí)質(zhì)是從fs模塊加載 3 個(gè)方法,其他方法不加載。即 ES6 可以在編譯時(shí)就完成模塊加載,效率要比 CommonJS 模塊的加載方式高。當(dāng)然,這也導(dǎo)致了沒法引用 ES6 模塊本身,因?yàn)樗?strong>不是對(duì)象。

由于 ES6 模塊是編譯時(shí)加載,使得靜態(tài)分析成為可能。有了它,就能進(jìn)一步拓寬 JavaScript 的語法,比如引入宏(macro)和類型檢驗(yàn)(type system)這些只能靠靜態(tài)分析實(shí)現(xiàn)的功能。

除了靜態(tài)加載帶來的各種好處,ES6 模塊還有以下好處:

不再需要UMD模塊格式了,將來服務(wù)器和瀏覽器都會(huì)支持 ES6 模塊格式。目前,通過各種工具庫,其實(shí)已經(jīng)做到了這一點(diǎn)。

將來瀏覽器的新API 就能用模塊格式提供,不再必須做成全局變量或者navigator對(duì)象的屬性。

不再需要對(duì)象作為命名空間(比如Math對(duì)象),未來這些功能可以通過模塊提供。

總結(jié)

CommonJS規(guī)范主要用于服務(wù)端編程,加載模塊是同步的,這并不適合在瀏覽器環(huán)境,因?yàn)橥揭馕吨枞虞d,瀏覽器資源是異步加載的,因此有了AMD、CMD解決方案。

AMD規(guī)范在瀏覽器環(huán)境中異步加載模塊,而且可以并行加載多個(gè)模塊。不過,AMD規(guī)范開發(fā)成本高,代碼的閱讀和書寫比較困難,模塊定義方式的語義不順暢。

CMD規(guī)范與AMD規(guī)范很相似,都用于瀏覽器編程,依賴就近,延遲執(zhí)行,可以很容易在Node.js中運(yùn)行。不過,依賴SPM打包,模塊的加載邏輯偏重。

ES6 在語言標(biāo)準(zhǔn)的層面上,實(shí)現(xiàn)了模塊功能,而且實(shí)現(xiàn)得相當(dāng)簡單,完全可以取代 CommonJS 和 AMD 規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。

以上是本篇文章的內(nèi)容,歡迎大家提出自己的想法,我們一起學(xué)習(xí)進(jìn)步,與君共勉。

參考資料

前端模塊化詳解(完整版)
ECMAScript 6 入門
近一萬字的ES6語法知識(shí)點(diǎn)補(bǔ)充
徹底搞清楚javascript中的require、import和export
CommonJS,AMD,CMD,ES6,require 和 import 詳解

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/103893.html

相關(guān)文章

  • python能做什么軟件?Python到底能干嘛,一文看懂

    摘要:語料庫是由文本構(gòu)成的數(shù)據(jù)集通過提供現(xiàn)成的文本數(shù)據(jù)來輔助文本處理。那么可以用來做什么呢我自己是一名從事是不錯(cuò)的入門選項(xiàng)。大數(shù)據(jù)和人工智能是機(jī)器學(xué)習(xí)和的主要開發(fā)語言。 Python培訓(xùn)有哪些內(nèi)容?很多零基礎(chǔ)學(xué)員不知道Python軟件是干什么用的?Python軟件是Python工程師編寫代碼時(shí)所需...

    YorkChen 評(píng)論0 收藏0
  • 一文帶你看懂cookie,面試前端不用愁

    摘要:的屬性在瀏覽器的控制臺(tái)中,可以直接輸入來查看。可以在瀏覽器的控制臺(tái)中看出哪些是類型的,下帶綠色對(duì)勾的即是,如圖只要是類型的在控制臺(tái)通過是獲取不到的,也不能進(jìn)行修改。當(dāng)會(huì)話過期或被放棄后,服務(wù)器將終止該會(huì)話。在中,用取代了。 本文由云+社區(qū)發(fā)表 在前端面試中,有一個(gè)必問的問題:請(qǐng)你談?wù)刢ookie和localStorage有什么區(qū)別啊? localStorage是H5中的一種瀏覽器本地存...

    notebin 評(píng)論0 收藏0
  • 一文讓你看懂IaaS、PaaS和SaaS

    摘要:以餃子為例,這時(shí)候需要準(zhǔn)備好面粉,剁好的餡料,再調(diào)配好需要的配料,還得等面粉發(fā)酵完畢后和面。包好餃子放進(jìn)蒸屜之中,蒸好后才能享用。與在自己家里面做不同,這里需要一個(gè)餃子的供應(yīng)商,這就是基礎(chǔ)設(shè)施即服務(wù)。在與相關(guān)人士聊云計(jì)算的時(shí)候,有時(shí)會(huì)從他們的最終蹦出諸如IaaS、PaaS和SaaS等相關(guān)名詞,聽的人一頭霧水,而往往與你聊的人,也只能用一些專業(yè)名字來解釋,這樣一來,就更加疑惑了。那么IaaS、...

    xuxueli 評(píng)論0 收藏0
  • 一文看懂云計(jì)算/霧計(jì)算/霾計(jì)算/邊緣計(jì)算/認(rèn)知計(jì)算等知識(shí)

    摘要:因此,年的埃里克施密特首次提出了云計(jì)算的概念,以及后來業(yè)界衍生出來霧計(jì)算霾計(jì)算邊緣計(jì)算等等一系列的計(jì)算方式,接下來,請(qǐng)跟隨小編一起去辨析一下它們到底指的是什么。未來的世界將是一個(gè)萬物互聯(lián)的時(shí)代,隨著物聯(lián)網(wǎng)行業(yè)技術(shù)標(biāo)準(zhǔn)的完善以及關(guān)鍵技術(shù)上的不斷突破,數(shù)據(jù)大爆炸時(shí)代將越走越近。就拿從2016年底開始風(fēng)靡全國甚至是海外市場的共享單車來說吧,據(jù)小編近日從摩數(shù)城市發(fā)布會(huì)獲悉,截止當(dāng)前,僅僅摩拜單車每天...

    Freeman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<