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

資訊專欄INFORMATION COLUMN

JavaScript模塊化開發的演進歷程

anonymoussf / 3196人閱讀

摘要:參考精讀模塊化發展模塊化七日談前端模塊化開發那點歷史本文先發布于我的個人博客模塊化開發的演進歷程,后續如有更新,可以查看原文。

Brendan Eich用了10天就創造了JavaScript,因為當時的需求定位,導致了在設計之初,在語言層就不包含很多高級語言的特性,其中就包括模塊這個特性,但是經過了這么多年的發展,如今對JavaScript的需求已經遠遠超出了Brendan Eich的預期,其中模塊化開發更是其中最大的需求之一。

尤其是2009年Node.js出現以后,CommonJS規范的落地極大的推動了整個社區的模塊化開發氛圍,并且隨之出現了AMD、CMD、UMD等等一系列可以在瀏覽器等終端實現的異步加載的模塊化方案。

此前,雖然自己也一直在推進模塊化開發,但是沒有深入了解過模塊化演進的歷史,直到最近看到了一篇文章《精讀JS模塊化發展》,文章總結了History of JavaScript這個開源項目中關于JavaScript模塊化演進的部分,細讀幾次之后,對于一些以前模棱兩可的東西,頓時清晰了不少,下面就以時間線總結一下自己的理解:

1999年的時候,絕大部分工程師做JS開發的時候就直接將變量定義在全局,做的好一些的或許會做一些文件目錄規劃,將資源歸類整理,這種方式被稱為直接定義依賴,舉個例子:

// greeting.js
var helloInLang = {
  en: "Hello world!",
  es: "?Hola mundo!",
  ru: "Привет мир!"
};
function writeHello(lang) {
  document.write(helloInLang[lang]);
}

// third_party_script.js
function writeHello() {
  document.write("The script is broken");
}

// index.html



  
  Basic example
  
  



但是,即使有規范的目錄結構,也不能避免由此而產生的大量全局變量,這就導致了一不小心就會有變量沖突的問題,就好比上面這個例子中的writeHello

于是在2002年左右,有人提出了命名空間模式的思路,用于解決遍地的全局變量,將需要定義的部分歸屬到一個對象的屬性上,簡單修改上面的例子,就能實現這種模式:

// greeting.js
var app = {};
app.helloInLang = {
  en: "Hello world!",
  es: "?Hola mundo!",
  ru: "Привет мир!"
};
app.writeHello = function (lang) {
  document.write(helloInLang[lang]);
}

// third_party_script.js
function writeHello() {
  document.write("The script is broken");
}

不過這種方式,毫無隱私可言,本質上就是全局對象,誰都可以來訪問并且操作,一點都不安全。

所以在2003年左右就有人提出利用IIFE結合Closures特性,以此解決私有變量的問題,這種模式被稱為閉包模塊化模式

// greeting.js
var greeting = (function() {
  var module = {};
  var helloInLang = {
    en: "Hello world!",
    es: "?Hola mundo!",
    ru: "Привет мир!",
  };

  module.getHello = function(lang) {
    return helloInLang[lang];
  };

  module.writeHello = function(lang) {
    document.write(module.getHello(lang));
  };

  return module;
})();

IIFE可以形成一個獨立的作用域,其中聲明的變量,僅在該作用域下,從而達到實現私有變量的目的,就如上面例子中的helloInLang,在該IIFE外是不能直接訪問和操作的,可以通過暴露一些方法來訪問和操作,比如說上面例子里面的getHellowriteHello2個方法,這就是所謂的Closures。

同時,不同模塊之間的引用也可以通過參數的形式來傳遞:

// x.js
// @require greeting.js
var x = (function(greeting) {
  var module = {};

  module.writeHello = function(lang) {
    document.write(greeting.getHello(lang));
  };

  return module;
})(greeting);

此外使用IIFE,還有2個好處:

提高性能:通過IIFE的參數傳遞常用全局對象window、document,在作用域內引用這些全局對象。JavaScript解釋器首先在作用域內查找屬性,然后一直沿著鏈向上查找,直到全局范圍,因此將全局對象放在IIFE作用域內可以提升js解釋器的查找速度和性能;

壓縮空間:通過參數傳遞全局對象,壓縮時可以將這些全局對象匿名為一個更加精簡的變量名;

在那個年代,除了這種解決思路以外,還有通過其它語言的協助來完成模塊化的解決思路,比如說模版依賴定義注釋依賴定義外部依賴定義等等,不過不常見,所以就不細說了,究其本源,它們想最終實現的方式都差不多。

不過,這些方案,雖然解決了依賴關系的問題,但是沒有解決如何管理這些模塊,或者說在使用時清晰描述出依賴關系,這點還是沒有被解決,可以說是少了一個管理者。

沒有管理者的時候,在實際項目中,得手動管理第三方的庫和項目封裝的模塊,就像下面這樣把所有需要的JS文件一個個按照依賴的順序加載進來:












如果頁面中使用的模塊數量越來越多,恐怕再有經驗的工程師也很難維護好它們之間的依賴關系了。

于是如LABjs之類的加載工具就橫空出世了,通過使用它的API,動態創建

閱讀需要支付1元查看
<