《JavaScript 模式》讀書筆記(2)— 基本技巧1
- 2020 年 3 月 17 日
- 筆記
這篇文章的主要內容,介紹了一些js編程中的基本技巧,其實這些技巧,大家在開發的過程中,或多或少都在使用,或者已經可以熟練的應用於自己的程式碼或項目中了。那麼,這篇文章,就一起來回顧下這些「基本技巧」。
編寫可維護的程式碼
我們想像一下,在我們的工作過程中,要去改一個bug,這個bug可能是由於之前十幾個人維護的項目,沒有規範,沒有JSLint,程式碼就像在大草原上弛聘一樣,隨心所欲,無欲無求。到了今天,剛好你接受了這個項目,測試發現了這個潛藏在系統中已久但今天才暴露的問題。然後,你看著這些程式碼,心裏面問候了程式碼作者的祖宗十六代,但是,不管怎麼樣,你還是要坐下來,安心的,潛心的從這些凌亂的,毫無規則的程式碼中,解決這個bug。
我相信很多人都遇到過這樣的問題,甚至在一些無規範的公司,企業,項目上,這實在是很普遍的事情(我現在正在經歷的)。那時,你就會發現,編寫可維護的程式碼有多重要。
易維護的程式碼意味著程式碼具有以下特性:
1. 閱讀性好。
2. 具有一致性。
3. 預見性好。
4. 看起來如同一個人編寫。
5. 有文檔。
盡量少用全局變數
全局變數的問題在於,它們在整個JavaScript應用或Web頁面內共享。它們生存於一個全局命名空間內,總有可能發生命名衝突。
JavaScript總是在不知不覺中就出人意料地創建了全局變數,其原因在於JavaScript 的兩個特性。第一個特性是JavaScript可直接使用變數,甚至無需聲明。第二個特性是JavaScript有一個暗示全局變數的概念,即任何變數,如果未經聲明,就為全局對象所有(也就像正確生命過的全局變數一樣可以訪問)。比如:
function sum (x,y) { //反模式:暗示全局變數 result = x + y; return result; }這個例子中,函數內部的變數result未經聲明就使用了,當然,在簡單環境下,這樣並不會有什麼問題,但是一旦在調用函數後,在外部空間使用了另外的result變數:
function sum(x, y) { result = x + y; return result; } sum(1, 2) var result = 6 console.log(result)所以,一個首要規則就是,使用var聲明變數。
function sum (x,y) { var result = x + y; return result; }另外一種創建隱式全局變數的反模式式帶有var聲明的鏈式賦值:
//反模式,不要使用 function foo() { var a = b = 0; //... }上面的程式碼,由於從右至左的操作符優先順序。所以,上面的程式碼實際是這樣的:
function foo() { var a = ( b = 0 ); //... }但是,如果對鏈式賦值的所有變數都進行了聲明,那麼就不用擔心會意想不到的創建了全局變數:
function foo() { var a ,b; //... a = b = 0; }另外,假設你的程式碼想要在不同的宿主環境(比如node和window)中都可以跑的很歡快,那麼就一定要注意全局變數的使用。因為,或許在window中不存在的變數,早已被node的全局變數所使用了。
變數釋放時的副作用
隱含全局變數與明確定義的全局變數有細微的不同,不同之處在於能否使用delete操作符撤銷變數。
- 使用var創建的全局變數(這類變數在函數外部創建)不能刪除。
- 不實用var創建的隱含全局變數(儘管它是在函數內部創建)可以刪除。
這表明隱含全局變數嚴格來講並不是真正的變數,而是全局對象的屬性。屬性可以通過delete操作符刪除,但是變數不可以。
var a = '1'; b = 2; (function () { c = 3; }()) delete a; delete b; delete c; console.log(typeof a) console.log(typeof b) console.log(typeof c)單一var模式
只使用一個var在函數頂部進行變數聲明是一種非常有用的模式。它的好處在於:
- 提供方一個單一的地址以查找到函數需要的所有局部變數。
- 防止出現變數在定義前就被使用的邏輯錯誤。
- 抱住牢記要聲明變數,以儘可能少的地使用全局變數。
- 更少的編碼(無論是輸入程式碼還是傳輸程式碼都更少了)。
比如:
function func() { var a = 1, b = 2, sum = a + b, obj = {}, i, j; }要記住,所有未初始化,且未聲明的變數,其值都為undefined。這句話不太容易理解,既然未聲明,那就說明不存在啊,沒錯,不存在就是undefined。那既然說到了undefined,簡單說下null的含義,null代表著存在,但是空。
提升:凌散變數的問題
JavaScript允許在函數的任意地方聲明多個變數,無論在哪裡聲明,效果都等同於在函數頂部進行聲明。這就是所謂的「提升」。當先使用後聲明的時候,就可能會導致邏輯錯誤。對於JavaScript而言,只要變數是在同一個範圍(同一個函數)里,就視為已經聲明,那排是在變數聲明前就使用。比如:
// 反模式 name = 'global'; // 全局變數 function func() { alert(name); // "未定義" var name = 'local'; alert(name); // "局部變數" } func();你以為第一個alert的結果是global么?那麼請再讀一遍加粗的那段話,實際上,程式碼是這樣執行的:
name = 'global'; // 全局變數 function func() { var name; alert(name); // "未定義" name = 'local'; alert(name); // "局部變數" } func();注意:事實上,程式碼處理上分為兩個階段:第一,這個階段創建變數、函數聲明及形式參數。這是解析和進入上線問的階段。第二個階段是程式碼運行時執行過程,創建函數表達和不合格標識符(未定義變數)。但為了實際使用的目的,我們使用了「提升」這個概念,儘管在ECMAScript標準中並不存在。 好了,我們這一篇的內容就到這裡,實際上,僅僅是基本技巧,後面還有不少的內容。我希望篇幅短一點,讀起來不那麼讓人厭煩。

