讀《編寫可維護的JavaScript》第六章總結

第六章 避免使用全局變量

JavaScript執行環境在不少方面都有其獨特之處,全局變量就是其中之一。「全局變量」是一個神祕的對象,它表示了腳本的最外層上下文。
javascript

在瀏覽器中,windows對象每每重載並等同於全局對象,所以任何在全局做用域聲明的變量和函數都是windows對象的屬性。html

6.1 全局變量帶來的問題

這個就不用照着書詳談了,當咱們進入團隊合做編寫代碼時,若你們自定義的變量都是直接掛載在windows對象上(也就是全局變量),很容易發生命名衝突。像這樣:前端

function sayColor() { alert(color); // 很差的作法: color是從哪來的?
       }

so, 儘可能避免定義全局變量java

若是這樣寫函數,也是有問題的,這是一個依賴於全局變量的函數。若是環境發生變化,函數極可能就失效了。windows

若是color被當作參數傳入,代碼可維護性會變得更佳。瀏覽器

function sayColor(color) { alert(color); 
       }

 so, 定義函數的時候,最好儘量多的將數據置於局部做用域內,在函數內定義的任何「東西」都應當採用這種作法,任何來自函數外部的數據都應當以參數的形式傳進來。框架

6.2 意外的全局變量

JS有個特性你們應該都懂: 就是沒有使用var聲明的變量會被當作全局變量ide

這個特性致使了有些人用一個單var語句聲明倆個變量,結果在第一個變量後不當心敲了分號而不是逗號從而把第二個變量自動建立成了全局變量。(不過個人IDE都提示了)模塊化

function doSomething() { var count = 10; title = "Maintainable JavaScript"; // 很差的寫法:建立了全局變量
         }

 

so, 這個問題解決的方法有不少,依靠現代的許多智能IDE(如:WebStorm之類的)或者JSLine和JSHint工具也能夠檢查出來並警告,或者直接將代碼採用嚴格模式。函數

   "use strict"; foo = 10; // 引用錯誤: foo未被定義

 

6.3 單全局變量方式

爲了解決前面的問題,最佳的辦法就是依賴儘量少的全局變量,即只建立一個全局變量。

單全局變量模式已經在各類流行的JavaScript類庫中普遍使用了。

  • YUI定義了惟一一個YUI全局對象。
  • jQuery定義了倆個全局對象,$和jQuery。只有在$被其餘的類庫使用了的狀況下:爲了不衝突,應當使用jQuery。
  • Dojo定義了一個dojo全局對象。

「單全局變量」的意思是所建立的這個惟一全局對象名是獨一無二的(不會和內置的API產生衝突),並將你全部的功能代碼都掛載到這個全局對象上。

所以每一個可能的全局變量都成爲你惟一全局變量的屬性。從而不會建立多個全局變量。

 // 這段代碼建立了4個全局對象:Book、Chapter一、Chapter2和Chapter3.
         function Book(title) { this.title = title; this.page = 1; } Book.prototype.turnPage = function(direction) { this.page += direction; } var Chapter1 = new Book("Introduction to Style Guidelines"); var Chapter2 = new Book("Bssic Formatting"); var Chapter3 = new Book("Comments");

單全局變量則只會建立一個全局對象並將這些對象都賦值爲它的屬性。

 var MaintainableJS = {}; MaintainableJS.Book = function(title) { this.title = title; this.page = 1; } MaintainableJS.Book.prototype.turnPage = function(direction) { this.page += direction; } MaintainableJS.Chapter1 = new MaintainableJS.Book("Introduction ti Style Guidelines"); MaintainableJS.Chapter2 = new MaintainableJS.Book("Basic Formatting"); MaintainableJS.Chapter3 = new MaintainableJS.Book("Comments");

 這段代碼已有一個全局對象,即 MaintainableJS, 其餘任何信息都掛載到這個對象上。由於團隊中的每一個人都知道這個全局對象,所以很容易作到繼續爲它添加屬性以免全局污染。

做者還介紹了關於命名空間(namespace)和模塊(modules)的概念。

命名空間我這裏就不說了。。由於這個概念就是很老的YUI框架運用的概念。如今的框架大多數是模塊化的,因此我重點作模塊的總結。

6.3.2 模塊

模塊這一節包含了大量我聽過但不沒有去弄懂的知識。

首先介紹模塊:另一種基於單全局變量的擴充方法是使用模塊,模塊是一種通用的功能片斷,他並沒用建立新的全局變量或命名空間。

相反,全部的這些代碼都存放於一個表示執行一個任務或發佈一個接口的單函數中。能夠用一個名稱來表示這個模塊,一樣這個模塊能夠依賴其餘模塊。

由於JavaScript自己不包含正式的模塊概念,天然也沒有模塊語法(期待ECMAScript6), 目前,世界上,有兩種比較流行的 JavaScript 模塊化體系,

一個是 Node 實現的 CommonJS,另一個是 AMD。

對於這倆者:瞭解他們也算是瞭解前端的歷史了。。我在這裏只將 看過的大神的解釋 拋出,由於這確實不是一篇帖子就能說明的。

首先是瞭解CMD,它是前端界的名人玉伯在寫完SeaJS後的推廣過程當中對模塊定義的規範化產出。(這是一種思想- -SeaJS已經沒落了)

接下來是AMD,它是 RequireJS 在推廣過程當中對模塊定義的規範化產出。

他本人在知乎上的回答就歸納了倆個規範:點這裏

另外一個是前端界的名人阮一峯對這倆個規範的解釋:點這裏

 6.4 零全局變量

徹底獨立的腳本纔會用到這種情形(注意:徹底無依賴)。

       (function() { "use strict"; var doc = win.document; // 在這裏定義其餘的變量

// 其餘相關代碼 }(Window));
相關文章
相關標籤/搜索